Add activity push notifications and registration patches
This commit is contained in:
@@ -15,6 +15,17 @@
|
||||
let sendQueue = Promise.resolve();
|
||||
let panel;
|
||||
|
||||
async function notificationTarget(notification) {
|
||||
const data = notification?.data || {};
|
||||
if (!/^[a-f0-9-]{36}$/.test(data.notification_id || '') || !/^[a-f0-9]{64}$/.test(data.session_tag || '')) return null;
|
||||
const response = await fetch('/api/push/session', {credentials: 'same-origin', cache: 'no-store'});
|
||||
if (!response.ok || stopped) return null;
|
||||
const session = await response.json();
|
||||
const native = await device.getInfo();
|
||||
if (!session.authenticated || session.session_tag !== data.session_tag || native.binding !== data.session_tag) return null;
|
||||
return '/notifications/' + data.notification_id;
|
||||
}
|
||||
|
||||
function notice(message, offerPermission = false) {
|
||||
if (!panel) {
|
||||
panel = document.createElement('section');
|
||||
@@ -130,9 +141,29 @@
|
||||
});
|
||||
}),
|
||||
push.addListener('registrationError', () => { if (!stopped) notice(texts.failed); }),
|
||||
push.addListener('pushNotificationActionPerformed', () => {
|
||||
// Do not navigate to arbitrary URLs supplied by a notification payload.
|
||||
location.assign('/');
|
||||
push.addListener('pushNotificationActionPerformed', async event => {
|
||||
try {
|
||||
const target = await notificationTarget(event.notification);
|
||||
if (target) location.assign(target);
|
||||
} catch (_) { /* A tap never bypasses current-session authorization. */ }
|
||||
}),
|
||||
push.addListener('pushNotificationReceived', async notification => {
|
||||
try {
|
||||
const target = await notificationTarget(notification);
|
||||
if (!target) return;
|
||||
document.getElementById('push-in-app-notice')?.remove();
|
||||
const banner = document.createElement('section');
|
||||
banner.id = 'push-in-app-notice';
|
||||
banner.className = 'native-push-panel';
|
||||
banner.setAttribute('role', 'status');
|
||||
const link = document.createElement('a');
|
||||
link.className = 'button';
|
||||
link.href = target;
|
||||
// Generic localized text; never insert remote HTML or private message content.
|
||||
link.textContent = texts.openNotification;
|
||||
banner.append(link);
|
||||
(document.querySelector('main') || document.body).prepend(banner);
|
||||
} catch (_) { /* Push reception cannot interrupt use of the app. */ }
|
||||
})
|
||||
]).then(() => {
|
||||
synchronize();
|
||||
|
||||
Reference in New Issue
Block a user