diff --git a/webpush/config.py b/webpush/config.py
index fa058ee..e69de29 100644
--- a/webpush/config.py
+++ b/webpush/config.py
@@ -1,5 +0,0 @@
-from django.conf import settings
-
-MANIFEST = {}
-if hasattr(settings,'WEBPUSH_SETTINGS'):
- MANIFEST["gcm_sender_id"] = settings.WEBPUSH_SETTINGS['GCM_ID']
diff --git a/webpush/forms.py b/webpush/forms.py
index 978d938..63fd5fc 100644
--- a/webpush/forms.py
+++ b/webpush/forms.py
@@ -3,7 +3,6 @@
from .models import Group, PushInformation, SubscriptionInfo
-
class WebPushForm(forms.Form):
group = forms.CharField(max_length=255, required=False)
status_type = forms.ChoiceField(choices=[
@@ -19,7 +18,7 @@ def save_or_delete(self, subscription, user, status_type, group_name):
if group_name:
group, created = Group.objects.get_or_create(name=group_name)
- data["group"] = group
+ data["group"] = group
data["subscription"] = subscription
@@ -36,9 +35,8 @@ class SubscriptionForm(forms.ModelForm):
class Meta:
model = SubscriptionInfo
- fields = ('browser', 'endpoint', 'auth', 'p256dh')
-
+ fields = ('endpoint', 'auth', 'p256dh')
- def get_or_save(self, subscription_data):
- subscription, created = SubscriptionInfo.objects.get_or_create(**subscription_data)
- return subscription
\ No newline at end of file
+ def get_or_save(self):
+ subscription, created = SubscriptionInfo.objects.get_or_create(**self.cleaned_data)
+ return subscription
diff --git a/webpush/models.py b/webpush/models.py
index d4b9ba5..6e244de 100644
--- a/webpush/models.py
+++ b/webpush/models.py
@@ -4,6 +4,7 @@
# Create your models here.
+
class Group(models.Model):
name = models.CharField(max_length=255, unique=True)
@@ -20,12 +21,12 @@ class PushInformation(models.Model):
subscription = models.ForeignKey(SubscriptionInfo, related_name='webpush_info')
group = models.ForeignKey(Group, related_name='webpush_info', blank=True, null=True)
- def save(self, force_insert=False, force_update=False, using=None):
+ def save(self, *args, **kwargs):
# Check whether user or the group field is present
# At least one field should be present there
# Through from the functionality its not possible, just in case! ;)
if self.user or self.group:
- super(PushInformation, self).save()
+ super(PushInformation, self).save(*args, **kwargs)
else:
raise FieldError('At least user or group should be present')
diff --git a/webpush/static/webpush/webpush.js b/webpush/static/webpush/webpush.js
index 3cf85bf..fde8445 100644
--- a/webpush/static/webpush/webpush.js
+++ b/webpush/static/webpush/webpush.js
@@ -78,8 +78,7 @@ window.addEventListener('load', function() {
function subscribe(reg) {
// Get the Subscription or register one
- getSubscription(reg)
- .then(
+ getSubscription(reg).then(
function(subscription) {
postSubscribeObj('subscribe',subscription);
}
@@ -91,16 +90,40 @@ function subscribe(reg) {
)
}
+function urlB64ToUint8Array(base64String) {
+ const padding = '='.repeat((4 - base64String.length % 4) % 4);
+ const base64 = (base64String + padding)
+ .replace(/\-/g, '+')
+ .replace(/_/g, '/');
+
+ const rawData = window.atob(base64);
+ const outputArray = new Uint8Array(rawData.length);
+
+ for (var i = 0; i < rawData.length; ++i) {
+ outputArray[i] = rawData.charCodeAt(i);
+ }
+ return outputArray;
+}
+
function getSubscription(reg) {
- return reg.pushManager.getSubscription()
- .then(
+ return reg.pushManager.getSubscription().then(
function(subscription) {
+ var metaObj, applicationServerKey, options;
// Check if Subscription is available
if (subscription) {
return subscription;
}
+
+ metaObj = document.querySelector('meta[name="django-webpush-vapid-key"]');
+ applicationServerKey = metaObj.content;
+ options = {
+ userVisibleOnly: true
+ };
+ if (applicationServerKey){
+ options.applicationServerKey = urlB64ToUint8Array(applicationServerKey)
+ }
// If not, register one
- return registration.pushManager.subscribe({ userVisibleOnly: true });
+ return registration.pushManager.subscribe(options)
}
)
}
diff --git a/webpush/static/webpush/webpush_serviceworker.js b/webpush/static/webpush/webpush_serviceworker.js
index 2c81ff5..e3c879c 100644
--- a/webpush/static/webpush/webpush_serviceworker.js
+++ b/webpush/static/webpush/webpush_serviceworker.js
@@ -14,7 +14,7 @@ self.addEventListener('push', function(event) {
// Show a notification with title 'ServiceWorker Cookbook' and use the payload
// as the body.
self.registration.showNotification(head, {
- body: body,
+ body: body
})
);
});
\ No newline at end of file
diff --git a/webpush/templates/webpush.html b/webpush/templates/webpush.html
index 3e9a026..f289f6c 100644
--- a/webpush/templates/webpush.html
+++ b/webpush/templates/webpush.html
@@ -3,5 +3,5 @@
-
+
{% endif %}
diff --git a/webpush/templatetags/webpush_notifications.py b/webpush/templatetags/webpush_notifications.py
index e1b84c3..14d62e5 100644
--- a/webpush/templatetags/webpush_notifications.py
+++ b/webpush/templatetags/webpush_notifications.py
@@ -1,4 +1,5 @@
from django import template
+from django.conf import settings
from django.core.urlresolvers import reverse
register = template.Library()
@@ -8,8 +9,9 @@
@register.inclusion_tag('webpush.html', takes_context=True)
def webpush(context):
group = context.get('webpush', {}).get('group')
+ vapid_public_key = getattr(settings, 'WEBPUSH_SETTINGS', {}).get('VAPID_PUBLIC_KEY', '')
request = context['request']
- return {'group': group, 'request': request}
+ return {'group': group, 'request': request, 'vapid_public_key': vapid_public_key}
@register.filter
diff --git a/webpush/urls.py b/webpush/urls.py
index 451ac6a..76750af 100644
--- a/webpush/urls.py
+++ b/webpush/urls.py
@@ -4,5 +4,4 @@
urlpatterns = [
url(r'^save_information', views.save_info, name='save_webpush_info'),
- url(r'^manifest', views.generate_manifest, name='webpush_manifest_json'),
]
diff --git a/webpush/utils.py b/webpush/utils.py
index 0a86f7b..8dcb86f 100644
--- a/webpush/utils.py
+++ b/webpush/utils.py
@@ -1,7 +1,7 @@
from django.conf import settings
from django.forms.models import model_to_dict
-from pywebpush import WebPusher
+from pywebpush import webpush
def send_notification_to_user(user, payload, ttl=0):
@@ -22,14 +22,24 @@ def send_notification_to_group(group_name, payload, ttl=0):
def _send_notification(push_info, payload, ttl):
subscription = push_info.subscription
subscription_data = _process_subscription_info(subscription)
- # Check if GCM info is provided in the settings
- if hasattr(settings,'WEBPUSH_SETTINGS'):
- gcm_key = settings.WEBPUSH_SETTINGS.get('GCM_KEY')
- else:
- gcm_key = None
- req = WebPusher(subscription_data).send(data=payload, ttl=ttl, gcm_key=gcm_key)
+ vapid_data = {}
+
+ webpush_settings = getattr(settings, 'WEBPUSH_SETTINGS', {})
+ vapid_private_key = webpush_settings.get('VAPID_PRIVATE_KEY')
+ vapid_admin_email = webpush_settings.get('VAPID_ADMIN_EMAIL')
+
+ # Vapid keys are optional, and mandatory only for Chrome.
+ # If Vapid key is provided, include vapid key and claims
+ if vapid_private_key:
+ vapid_data = {
+ 'vapid_private_key': vapid_private_key,
+ 'vapid_claims': {"sub": "mailto:{}".format(vapid_admin_email)}
+ }
+
+ req = webpush(subscription_info=subscription_data, data=payload, ttl=ttl, **vapid_data)
return req
+
def _process_subscription_info(subscription):
subscription_data = model_to_dict(subscription, exclude=["browser", "id"])
endpoint = subscription_data.pop("endpoint")
diff --git a/webpush/views.py b/webpush/views.py
index 30fd2e4..d6ab4e5 100644
--- a/webpush/views.py
+++ b/webpush/views.py
@@ -1,13 +1,8 @@
import json
-
-from django.conf import settings
-from django.core.exceptions import FieldError
-from django.http import HttpResponse, JsonResponse
-from django.shortcuts import render
+from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST, require_GET
-from .config import MANIFEST
from .forms import WebPushForm, SubscriptionForm
@@ -37,7 +32,7 @@ def save_info(request):
if request.user.is_authenticated() or group_name:
# Save the subscription info with subscription data
# as the subscription data is a dictionary and its valid
- subscription = subscription_form.get_or_save(subscription_data)
+ subscription = subscription_form.get_or_save()
web_push_form.save_or_delete(
subscription=subscription, user=request.user,
status_type=status_type, group_name=group_name)
@@ -52,14 +47,6 @@ def save_info(request):
return HttpResponse(status=400)
-@require_GET
-def generate_manifest(request):
- if hasattr(settings,'WEBPUSH_SETTINGS'):
- return JsonResponse(MANIFEST)
- else:
- return HttpResponse(status=404)
-
-
def process_subscription_data(post_data):
"""Process the subscription data according to out model"""
subscription_data = post_data.pop("subscription", {})