feat: Auto-unsubscribe push on logout, force resubscribe on login

- Добавлена автоматическая отписка от Web Push при выходе
- При входе принудительно переподписываем пользователя
- Очищаем старую подписку из localStorage перед новой
- Это исправляет AbortError из-за старых подписок с другими VAPID ключами
This commit is contained in:
Игорь Надеин 2026-01-06 08:11:24 +03:00
parent fc6a6b0816
commit d36e9dfd7c
2 changed files with 51 additions and 12 deletions

View File

@ -47,6 +47,33 @@ export function initLogoutModal(options) {
return { destroy: () => {} };
}
/**
* Отписывается от push-уведомлений перед выходом
*/
async function unsubscribeFromPush() {
if (window.pushNotifications && typeof window.pushNotifications.unsubscribe === 'function') {
try {
await window.pushNotifications.unsubscribe();
console.log('[Logout] Push подписка удалена');
} catch (error) {
console.error('[Logout] Ошибка отписки:', error);
}
}
// Очищаем localStorage
localStorage.removeItem('push_endpoint');
}
/**
* Обработчик отправки формы logout
*/
function handleLogoutSubmit(event) {
// Не preventDefault - позволяем форме отправиться
// Но сначала отписываемся асинхронно
unsubscribeFromPush().catch(err => {
console.error('[Logout] Unsubscribe error:', err);
});
}
/**
* Возврат на предыдущую страницу или указанный URL.
*/
@ -117,6 +144,12 @@ export function initLogoutModal(options) {
cancelButton.addEventListener('click', handleCancelClick);
overlay.addEventListener('click', handleOverlayClick);
window.addEventListener('keydown', handleKeyDown);
// Добавляем обработчик на форму logout
const logoutForm = confirmButton.closest('form');
if (logoutForm) {
logoutForm.addEventListener('submit', handleLogoutSubmit);
}
// Автофокус на кнопке подтверждения после небольшой задержки
setTimeout(() => {

View File

@ -149,18 +149,24 @@
if (initialized) {
console.log('[WebPush] Инициализирован, подписка:', pushNotifications.isSubscribed);
// Если разрешение еще не спрошено и пользователь не подписан -
// можно показать промо для подписки (опционально)
if (pushNotifications.getPermissionStatus() === 'default' && !pushNotifications.isSubscribed) {
// Автоматически не подписываем, ждем явного действия пользователя
// Можно добавить кнопку в UI для подписки
console.log('[WebPush] Пользователь еще не подписан на push-уведомления');
}
// Если разрешение дано, но нет подписки - подписываем
if (pushNotifications.getPermissionStatus() === 'granted' && !pushNotifications.isSubscribed) {
console.log('[WebPush] Разрешение есть, подписываемся...');
await pushNotifications.subscribe();
// Если разрешение дано - всегда переподписываем при входе
// Это гарантирует, что подписка привязана к текущему пользователю
if (pushNotifications.getPermissionStatus() === 'granted') {
console.log('[WebPush] Разрешение есть, переподписываемся...');
// Очищаем старый endpoint из localStorage
localStorage.removeItem('push_endpoint');
// Подписываемся (метод subscribe сам удалит старую подписку)
const subscribed = await pushNotifications.subscribe();
if (subscribed) {
console.log('[WebPush] ✅ Успешно подписан');
} else {
console.warn('[WebPush] ⚠️ Не удалось подписаться');
}
} else if (pushNotifications.getPermissionStatus() === 'default') {
console.log('[WebPush] Пользователь еще не дал разрешение на уведомления');
}
}
});