Push: refactor registerer.js

chats-push-2
Alex Gleason 2020-09-24 22:38:33 -05:00
rodzic e8ea75af73
commit f305b2e98e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
1 zmienionych plików z 39 dodań i 20 usunięć

Wyświetl plik

@ -34,22 +34,45 @@ const subscribe = (registration, getState) =>
const unsubscribe = ({ registration, subscription }) => const unsubscribe = ({ registration, subscription }) =>
subscription ? subscription.unsubscribe().then(() => registration) : registration; subscription ? subscription.unsubscribe().then(() => registration) : registration;
const sendSubscriptionToBackend = (subscription, me) => { const subscriptionToParams = subscription => {
const params = { subscription }; const sub = subscription.toJSON();
return {
endpoint: sub.endpoint,
keys: sub.keys,
};
};
if (me) { const sendSubscriptionToBackend = (subscription, getState) => {
const data = pushNotificationsSetting.get(me); const params = {
if (data) { subscription: subscriptionToParams(subscription),
params.data = data; data: {
} // TODO: Make configurable
} alerts: {
follow: true,
favourite: true,
reblog: true,
mention: true,
poll: true,
'pleroma:chat_mention': true,
},
},
};
return api().post('/api/web/push_subscriptions', params).then(response => response.data); return api(getState).post('/api/v1/push/subscription', params)
.then(response => response.data);
}; };
// Last one checks for payload support: https://web-push-book.gauntface.com/chapter-06/01-non-standards-browsers/#no-payload // Last one checks for payload support: https://web-push-book.gauntface.com/chapter-06/01-non-standards-browsers/#no-payload
const supportsPushNotifications = ('serviceWorker' in navigator && 'PushManager' in window && 'getKey' in PushSubscription.prototype); const supportsPushNotifications = ('serviceWorker' in navigator && 'PushManager' in window && 'getKey' in PushSubscription.prototype);
// Check that the VAPID public key did not change
const vapidKeyMatches = (subscription, getState) => {
const currentServerKey = (new Uint8Array(subscription.options.applicationServerKey)).toString();
const subscriptionServerKey = urlBase64ToUint8Array(getApplicationServerKey(getState)).toString();
return currentServerKey === subscriptionServerKey;
};
export function register() { export function register() {
return (dispatch, getState) => { return (dispatch, getState) => {
const me = getState().get('me'); const me = getState().get('me');
@ -66,26 +89,21 @@ export function register() {
.then(({ registration, subscription }) => { .then(({ registration, subscription }) => {
if (subscription !== null) { if (subscription !== null) {
// We have a subscription, check if it is still valid // We have a subscription, check if it is still valid
const currentServerKey = (new Uint8Array(subscription.options.applicationServerKey)).toString(); // TODO: Also compare `subscription.endpoint`
const subscriptionServerKey = urlBase64ToUint8Array(getApplicationServerKey(getState)).toString(); if (vapidKeyMatches(subscription, getState)) {
const serverEndpoint = getState().getIn(['push_notifications', 'subscription', 'endpoint']);
// If the VAPID public key did not change and the endpoint corresponds
// to the endpoint saved in the backend, the subscription is valid
if (subscriptionServerKey === currentServerKey && subscription.endpoint === serverEndpoint) {
return subscription; return subscription;
} else { } else {
// Something went wrong, try to subscribe again // Something went wrong, try to subscribe again
return unsubscribe({ registration, subscription }).then(registration => { return unsubscribe({ registration, subscription }).then(registration => {
return subscribe(registration, getState); return subscribe(registration, getState);
}).then( }).then(
subscription => sendSubscriptionToBackend(subscription, me)); subscription => sendSubscriptionToBackend(subscription, getState));
} }
} }
// No subscription, try to subscribe // No subscription, try to subscribe
return subscribe(registration, getState).then( return subscribe(registration, getState).then(
subscription => sendSubscriptionToBackend(subscription, me)); subscription => sendSubscriptionToBackend(subscription, getState));
}) })
.then(subscription => { .then(subscription => {
// If we got a PushSubscription (and not a subscription object from the backend) // If we got a PushSubscription (and not a subscription object from the backend)
@ -102,6 +120,8 @@ export function register() {
console.warn('Your browser supports Web Push Notifications, but does not seem to implement the VAPID protocol.'); console.warn('Your browser supports Web Push Notifications, but does not seem to implement the VAPID protocol.');
} else if (error.code === 5 && error.name === 'InvalidCharacterError') { } else if (error.code === 5 && error.name === 'InvalidCharacterError') {
console.error('The VAPID public key seems to be invalid:', getApplicationServerKey(getState)); console.error('The VAPID public key seems to be invalid:', getApplicationServerKey(getState));
} else {
console.error(error);
} }
// Clear alerts and hide UI settings // Clear alerts and hide UI settings
@ -124,12 +144,11 @@ export function register() {
export function saveSettings() { export function saveSettings() {
return (_, getState) => { return (_, getState) => {
const state = getState().get('push_notifications'); const state = getState().get('push_notifications');
const subscription = state.get('subscription');
const alerts = state.get('alerts'); const alerts = state.get('alerts');
const data = { alerts }; const data = { alerts };
const me = getState().get('me'); const me = getState().get('me');
api().put(`/api/web/push_subscriptions/${subscription.get('id')}`, { api(getState).put('/api/v1/push/subscription', {
data, data,
}).then(() => { }).then(() => {
if (me) { if (me) {