github peterdu1109/NotifySync v5.5.12.8-beta9
🧪 NotifySync v5.5.12.8-beta9

2 hours ago

🧪 Beta channel — Pre-release. Add the beta repo URL: https://raw.githubusercontent.com/peterdu1109/NotifySync/main/repository-beta.json. On 5.5.12.7-beta8, Jellyfin offers this as a regular update.

🇬🇧 English

📝 In Short

Security fix on an admin endpoint, mobile-friendly category mapping reorder, polish on the "Scan collections now" feedback, and a consolidated What's New section in the README covering everything that changed since stable.

🐛 What's Fixed / ✨ What's New

  • Admin authorization on the history refresh endpoint/Refresh was open to any authenticated user, who could trigger costly rebuilds and wipe upgrade badges from their own account. The endpoint now properly requires the Administrator role, matching the other admin endpoints.
  • Category mappings can be reordered on touch devices — The desktop drag-and-drop is replaced by up / down arrow buttons next to each mapping row. They disable themselves at the list edges. Works the same on PC and mobile.
  • "Scan collections now" reports when nothing's monitored — Clicking the button with no monitored collection used to silently claim success. Now you get a clear warning "No collections monitored — pick at least one in the Collections tab."
  • No more dangling links in the Deletions tab — When a notification gets cleaned up by the bell quota, any DeletedItems row that pointed at it as the upgrade replacement now has its link cleared automatically.
  • README — "What's New in 5.5.12" — Bilingual summary of every change in the 5.5.12 series. Worth a look if you want to see the full picture at a glance.

🔧 Technical details for the curious

Security fix. NotifyController.Refresh() gained the same admin check pattern used by /DeletedItems and /ScanCollections:

if (!User.IsInRole("Administrator")
    && !string.Equals(User.FindFirst("Jellyfin-IsApiKey")?.Value, "true", StringComparison.OrdinalIgnoreCase))
{
    return Forbid();
}

Without it, a regular user could POST /NotifySync/Refresh and trigger PopulateInitialHistory — which wipes the Notifications table and rebuilds it via ReplaceAllNotifications. Wasted resources at best, badge corruption at worst.

Mapping reorder. The previous implementation used row.draggable = true plus HTML5 dragstart/dragover/drop handlers. That API is not exposed to touch events on iOS/Android web views. Replaced with a .ns-move-controls column containing two arrow_upward / arrow_downward buttons that splice the CategoryMappings array up or down and re-render. Edge buttons are disabled (isFirst / isLast).

Empty-collection signal. ScanCollectionsNow returns { Message, NoCollections: true } when Plugin.Instance.Configuration.EnabledCollections is empty. The admin page checks res.NoCollections and surfaces a warn toast (new translation key scanColEmptyMsg).

Cascade clear. DeleteNotifications now wraps both a DELETE FROM Notifications and an UPDATE DeletedItems SET MatchedNotificationId = NULL WHERE MatchedNotificationId = ? in the same transaction, so a notification removal can't leave a DeletedItems row pointing at a no-longer-existing notification ID.

README synth. A new top-level "What's New in 5.5.12" section in both EN and FR sits between the table of contents and Quick Start. Organized by user-visible theme (detection, grouping, persistence, admin diagnostics, etc.), not by beta number — so when the 5.5.12 series goes stable, the section reads as a clean changelog rather than a development log.

Internal plugin version 5.5.12.8. User-facing strings read 5.5.12.8-beta9 (tag, release title, README badge, admin badge, client.js banner).


🇫🇷 Français

📝 En bref

Fix de sécurité sur un endpoint admin, réordonnancement des mappings de catégorie compatible tactile, polish du retour du bouton "Scanner les collections", et une section Quoi de Neuf consolidée dans le README couvrant tous les changements depuis stable.

🐛 Corrections / ✨ Quoi de Neuf

  • Autorisation admin sur l'endpoint de régénération/Refresh était ouvert à n'importe quel utilisateur authentifié, qui pouvait déclencher des rebuilds coûteux et effacer les badges d'upgrade depuis son propre compte. L'endpoint exige maintenant correctement le rôle Administrateur, comme les autres endpoints admin.
  • Les mappings de catégorie sont réordonnables sur mobile — Le drag-and-drop desktop est remplacé par des boutons flèche haut / flèche bas à côté de chaque ligne de mapping. Ils se désactivent automatiquement aux extrémités. Fonctionne pareil sur PC et mobile.
  • "Scanner les collections" indique quand rien n'est surveillé — Cliquer le bouton sans aucune collection surveillée prétendait silencieusement réussir. Maintenant un avertissement clair s'affiche : "Aucune collection surveillée — cochez-en au moins une dans l'onglet Collections."
  • Plus de liens morts dans l'onglet Suppressions — Quand une notification est nettoyée par le quota de la cloche, toute ligne DeletedItems qui la référençait comme remplacement d'upgrade voit son lien nettoyé automatiquement.
  • README — "Quoi de Neuf en 5.5.12" — Récap bilingue de tous les changements de la série 5.5.12. À regarder pour avoir la vue d'ensemble d'un coup d'œil.

🔧 Détails techniques pour les curieux

Fix sécurité. NotifyController.Refresh() a gagné le même pattern de check admin utilisé par /DeletedItems et /ScanCollections :

if (!User.IsInRole("Administrator")
    && !string.Equals(User.FindFirst("Jellyfin-IsApiKey")?.Value, "true", StringComparison.OrdinalIgnoreCase))
{
    return Forbid();
}

Sans ça, un user normal pouvait POST /NotifySync/Refresh et déclencher PopulateInitialHistory — qui wipe la table Notifications et la reconstruit via ReplaceAllNotifications. Gaspillage de ressources au mieux, corruption de badges au pire.

Réordonnancement des mappings. L'implémentation précédente utilisait row.draggable = true plus des handlers HTML5 dragstart/dragover/drop. Cette API n'est pas exposée aux événements tactiles sur iOS/Android web views. Remplacée par une colonne .ns-move-controls contenant deux boutons arrow_upward / arrow_downward qui splicent le tableau CategoryMappings en haut/en bas et re-renderent. Les boutons aux bords sont désactivés (isFirst / isLast).

Signal collection vide. ScanCollectionsNow retourne { Message, NoCollections: true } quand Plugin.Instance.Configuration.EnabledCollections est vide. La page admin check res.NoCollections et surface un toast warn (nouvelle clé de traduction scanColEmptyMsg).

Cascade clear. DeleteNotifications wrap maintenant à la fois un DELETE FROM Notifications et un UPDATE DeletedItems SET MatchedNotificationId = NULL WHERE MatchedNotificationId = ? dans la même transaction, donc une suppression de notification ne peut plus laisser une ligne DeletedItems pointer vers un ID de notification qui n'existe plus.

Synthèse README. Une nouvelle section top-level "Quoi de Neuf en 5.5.12" en EN et FR se trouve entre le sommaire et le démarrage rapide. Organisée par thème visible utilisateur (détection, grouping, persistance, diagnostic admin, etc.), pas par numéro de beta — donc quand la série 5.5.12 passera stable, la section se lira comme un changelog propre plutôt qu'un journal de développement.

Version interne du plugin 5.5.12.8. Les strings user-facing affichent 5.5.12.8-beta9 (tag, titre release, badge README, badge admin, bannière client.js).

Don't miss a new NotifySync release

NewReleases is sending notifications on new releases.