+
{{ label }}
-
-
- -
-
-
{{ item.text }}
+
+
+
+ -
+
{{ item.text }}
+
+
+ checkmark
+
+
+
+ -
+
+ {{ $strings.MessageNoItems }}
-
- checkmark
-
-
- -
-
- {{ $strings.MessageNoItems }}
-
-
-
+
+
@@ -48,7 +49,12 @@ export default {
data() {
return {
showMenu: false,
- menu: null
+ menu: null,
+ clickOutsideObj: {
+ handler: this.closeMenu,
+ events: ['mousedown'],
+ isActive: true
+ }
}
},
computed: {
diff --git a/client/strings/da.json b/client/strings/da.json
index cf9f836bb7..768bb724f4 100644
--- a/client/strings/da.json
+++ b/client/strings/da.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Tilføj {0} Bøger til Samling",
"LabelAddToPlaylist": "Tilføj til Afspilningsliste",
"LabelAddToPlaylistBatch": "Tilføj {0} Elementer til Afspilningsliste",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Alle",
"LabelAllUsers": "Alle Brugere",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Allerede i dit bibliotek",
"LabelAppend": "Tilføj",
"LabelAuthor": "Forfatter",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Fravælg Alle",
"LabelDevice": "Enheds",
"LabelDeviceInfo": "Enhedsinformation",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Mappe",
"LabelDiscFromFilename": "Disk fra Filnavn",
"LabelDiscFromMetadata": "Disk fra Metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Sæson",
"LabelSelectAllEpisodes": "Vælg alle episoder",
"LabelSelectEpisodesShowing": "Vælg {0} episoder vist",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Send e-bog til...",
"LabelSequence": "Sekvens",
"LabelSeries": "Serie",
diff --git a/client/strings/de.json b/client/strings/de.json
index e9242a3eed..f7cf8b68e9 100644
--- a/client/strings/de.json
+++ b/client/strings/de.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Füge {0} Hörbüch(er)/Podcast(s) der Sammlung hinzu",
"LabelAddToPlaylist": "Zur Wiedergabeliste hinzufügen",
"LabelAddToPlaylistBatch": "Füge {0} Hörbüch(er)/Podcast(s) der Wiedergabeliste hinzu",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Alle",
"LabelAllUsers": "Alle Benutzer",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "In der Bibliothek vorhanden",
"LabelAppend": "Anhängen",
"LabelAuthor": "Autor",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Alles abwählen",
"LabelDevice": "Gerät",
"LabelDeviceInfo": "Geräteinformationen",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Verzeichnis",
"LabelDiscFromFilename": "CD aus dem Dateinamen",
"LabelDiscFromMetadata": "CD aus den Metadaten",
@@ -394,6 +398,7 @@
"LabelSeason": "Staffel",
"LabelSelectAllEpisodes": "Alle Episoden auswählen",
"LabelSelectEpisodesShowing": "{0} ausgewählte Episoden werden angezeigt",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "E-Book senden an...",
"LabelSequence": "Reihenfolge",
"LabelSeries": "Serien",
diff --git a/client/strings/en-us.json b/client/strings/en-us.json
index bfaac5ea47..1366c762af 100644
--- a/client/strings/en-us.json
+++ b/client/strings/en-us.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Add {0} Books to Collection",
"LabelAddToPlaylist": "Add to Playlist",
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "All",
"LabelAllUsers": "All Users",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Author",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Deselect All",
"LabelDevice": "Device",
"LabelDeviceInfo": "Device Info",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Directory",
"LabelDiscFromFilename": "Disc from Filename",
"LabelDiscFromMetadata": "Disc from Metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Season",
"LabelSelectAllEpisodes": "Select all episodes",
"LabelSelectEpisodesShowing": "Select {0} episodes showing",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Send Ebook to...",
"LabelSequence": "Sequence",
"LabelSeries": "Series",
diff --git a/client/strings/es.json b/client/strings/es.json
index ca659fc8e4..0ac0a96018 100644
--- a/client/strings/es.json
+++ b/client/strings/es.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Se Añadieron {0} Libros a la Colección",
"LabelAddToPlaylist": "Añadido a la Lista de Reproducción",
"LabelAddToPlaylistBatch": "Se Añadieron {0} Artículos a la Lista de Reproducción",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Todos",
"LabelAllUsers": "Todos los Usuarios",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Ya en la Biblioteca",
"LabelAppend": "Adjuntar",
"LabelAuthor": "Autor",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Deseleccionar Todos",
"LabelDevice": "Dispositivo",
"LabelDeviceInfo": "Información de Dispositivo",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Directorio",
"LabelDiscFromFilename": "Disco a partir del Nombre del Archivo",
"LabelDiscFromMetadata": "Disco a partir de Metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Temporada",
"LabelSelectAllEpisodes": "Seleccionar todos los episodios",
"LabelSelectEpisodesShowing": "Seleccionar los {0} episodios visibles",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Enviar Ebook a...",
"LabelSequence": "Secuencia",
"LabelSeries": "Series",
diff --git a/client/strings/fr.json b/client/strings/fr.json
index be62414205..5ad80723f4 100644
--- a/client/strings/fr.json
+++ b/client/strings/fr.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Ajout de {0} livres à la lollection",
"LabelAddToPlaylist": "Ajouter à la liste de lecture",
"LabelAddToPlaylistBatch": "{0} éléments ajoutés à la liste de lecture",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Tout",
"LabelAllUsers": "Tous les utilisateurs",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Déjà dans la bibliothèque",
"LabelAppend": "Ajouter",
"LabelAuthor": "Auteur",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Tout déselectionner",
"LabelDevice": "Appareil",
"LabelDeviceInfo": "Détail de l’appareil",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Répertoire",
"LabelDiscFromFilename": "Disque depuis le fichier",
"LabelDiscFromMetadata": "Disque depuis les métadonnées",
@@ -394,6 +398,7 @@
"LabelSeason": "Saison",
"LabelSelectAllEpisodes": "Sélectionner tous les épisodes",
"LabelSelectEpisodesShowing": "Sélectionner {0} episode(s) en cours",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Envoyer le livre numérique à...",
"LabelSequence": "Séquence",
"LabelSeries": "Séries",
diff --git a/client/strings/gu.json b/client/strings/gu.json
index eb24cd6a60..d71c9f1767 100644
--- a/client/strings/gu.json
+++ b/client/strings/gu.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Add {0} Books to Collection",
"LabelAddToPlaylist": "Add to Playlist",
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "All",
"LabelAllUsers": "All Users",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Author",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Deselect All",
"LabelDevice": "Device",
"LabelDeviceInfo": "Device Info",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Directory",
"LabelDiscFromFilename": "Disc from Filename",
"LabelDiscFromMetadata": "Disc from Metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Season",
"LabelSelectAllEpisodes": "Select all episodes",
"LabelSelectEpisodesShowing": "Select {0} episodes showing",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Send Ebook to...",
"LabelSequence": "Sequence",
"LabelSeries": "Series",
diff --git a/client/strings/hi.json b/client/strings/hi.json
index 4ffa2bd35f..51b2e7629f 100644
--- a/client/strings/hi.json
+++ b/client/strings/hi.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Add {0} Books to Collection",
"LabelAddToPlaylist": "Add to Playlist",
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "All",
"LabelAllUsers": "All Users",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Author",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Deselect All",
"LabelDevice": "Device",
"LabelDeviceInfo": "Device Info",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Directory",
"LabelDiscFromFilename": "Disc from Filename",
"LabelDiscFromMetadata": "Disc from Metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Season",
"LabelSelectAllEpisodes": "Select all episodes",
"LabelSelectEpisodesShowing": "Select {0} episodes showing",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Send Ebook to...",
"LabelSequence": "Sequence",
"LabelSeries": "Series",
diff --git a/client/strings/hr.json b/client/strings/hr.json
index 71090fe19d..e04343a09c 100644
--- a/client/strings/hr.json
+++ b/client/strings/hr.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Add {0} Books to Collection",
"LabelAddToPlaylist": "Add to Playlist",
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "All",
"LabelAllUsers": "Svi korisnici",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Autor",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Odznači sve",
"LabelDevice": "Uređaj",
"LabelDeviceInfo": "O uređaju",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Direktorij",
"LabelDiscFromFilename": "CD iz imena datoteke",
"LabelDiscFromMetadata": "CD iz metapodataka",
@@ -394,6 +398,7 @@
"LabelSeason": "Sezona",
"LabelSelectAllEpisodes": "Select all episodes",
"LabelSelectEpisodesShowing": "Select {0} episodes showing",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Send Ebook to...",
"LabelSequence": "Sekvenca",
"LabelSeries": "Serije",
diff --git a/client/strings/it.json b/client/strings/it.json
index 88f3c5b75f..747d7420ca 100644
--- a/client/strings/it.json
+++ b/client/strings/it.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Aggiungi {0} Libri alla Raccolta",
"LabelAddToPlaylist": "aggiungi alla Playlist",
"LabelAddToPlaylistBatch": "Aggiungi {0} file alla Playlist",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Tutti",
"LabelAllUsers": "Tutti gli Utenti",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Già esistente nella libreria",
"LabelAppend": "Appese",
"LabelAuthor": "Autore",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Deseleziona Tutto",
"LabelDevice": "Dispositivo",
"LabelDeviceInfo": "Info Dispositivo",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Elenco",
"LabelDiscFromFilename": "Disco dal nome file",
"LabelDiscFromMetadata": "Disco dal Metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Stagione",
"LabelSelectAllEpisodes": "Seleziona tutti gli Episodi",
"LabelSelectEpisodesShowing": "Episodi {0} selezionati ",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Invia ebook a...",
"LabelSequence": "Sequenza",
"LabelSeries": "Serie",
diff --git a/client/strings/lt.json b/client/strings/lt.json
index 6e85d68956..ebc6b55888 100644
--- a/client/strings/lt.json
+++ b/client/strings/lt.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Pridėti {0} knygas į kolekciją",
"LabelAddToPlaylist": "Pridėti į grojaraštį",
"LabelAddToPlaylistBatch": "Pridėti {0} elementus į grojaraštį",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Visi",
"LabelAllUsers": "Visi naudotojai",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Jau yra jūsų bibliotekoje",
"LabelAppend": "Pridėti",
"LabelAuthor": "Autorius",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Išvalyti pasirinktus",
"LabelDevice": "Įrenginys",
"LabelDeviceInfo": "Įrenginio informacija",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Katalogas",
"LabelDiscFromFilename": "Diskas pagal failo pavadinimą",
"LabelDiscFromMetadata": "Diskas pagal metaduomenis",
@@ -394,6 +398,7 @@
"LabelSeason": "Sezonas",
"LabelSelectAllEpisodes": "Pažymėti visus epizodus",
"LabelSelectEpisodesShowing": "Pažymėti {0} rodomus epizodus",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Siųsti e-knygą į...",
"LabelSequence": "Seka",
"LabelSeries": "Serija",
diff --git a/client/strings/nl.json b/client/strings/nl.json
index 9391f332f8..06aed90459 100644
--- a/client/strings/nl.json
+++ b/client/strings/nl.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "{0} boeken toevoegen aan collectie",
"LabelAddToPlaylist": "Toevoegen aan afspeellijst",
"LabelAddToPlaylistBatch": "{0} onderdelen toevoegen aan afspeellijst",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Alle",
"LabelAllUsers": "Alle gebruikers",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Reeds in je bibliotheek",
"LabelAppend": "Achteraan toevoegen",
"LabelAuthor": "Auteur",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Deselecteer alle",
"LabelDevice": "Apparaat",
"LabelDeviceInfo": "Apparaat info",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Map",
"LabelDiscFromFilename": "Schijf uit bestandsnaam",
"LabelDiscFromMetadata": "Schijf uit metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Seizoen",
"LabelSelectAllEpisodes": "Selecteer alle afleveringen",
"LabelSelectEpisodesShowing": "Selecteer {0} afleveringen laten zien",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Stuur ebook naar...",
"LabelSequence": "Sequentie",
"LabelSeries": "Serie",
diff --git a/client/strings/no.json b/client/strings/no.json
index ac16d3511e..7fcd1c96ab 100644
--- a/client/strings/no.json
+++ b/client/strings/no.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Legg {0} bøker til samling",
"LabelAddToPlaylist": "Legg til i spilleliste",
"LabelAddToPlaylistBatch": "Legg {0} enheter til i spilleliste",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Alle",
"LabelAllUsers": "Alle brukere",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Allerede i biblioteket",
"LabelAppend": "Legge til",
"LabelAuthor": "Forfatter",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Fjern valg",
"LabelDevice": "Enhet",
"LabelDeviceInfo": "Enhetsinformasjon",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Mappe",
"LabelDiscFromFilename": "Disk fra filnavn",
"LabelDiscFromMetadata": "Disk fra metadata",
@@ -394,6 +398,7 @@
"LabelSeason": "Sesong",
"LabelSelectAllEpisodes": "Velg alle episoder",
"LabelSelectEpisodesShowing": "Velg {0} episoder vist",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Send Ebok til...",
"LabelSequence": "Sekvens",
"LabelSeries": "Serier",
diff --git a/client/strings/pl.json b/client/strings/pl.json
index b92cb894f7..dd3c1d4adc 100644
--- a/client/strings/pl.json
+++ b/client/strings/pl.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Dodaj {0} książki do kolekcji",
"LabelAddToPlaylist": "Add to Playlist",
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "All",
"LabelAllUsers": "Wszyscy użytkownicy",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Autor",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Odznacz wszystko",
"LabelDevice": "Urządzenie",
"LabelDeviceInfo": "Informacja o urządzeniu",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Katalog",
"LabelDiscFromFilename": "Oznaczenie dysku z nazwy pliku",
"LabelDiscFromMetadata": "Oznaczenie dysku z metadanych",
@@ -394,6 +398,7 @@
"LabelSeason": "Sezon",
"LabelSelectAllEpisodes": "Select all episodes",
"LabelSelectEpisodesShowing": "Select {0} episodes showing",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Send Ebook to...",
"LabelSequence": "Kolejność",
"LabelSeries": "Serie",
diff --git a/client/strings/ru.json b/client/strings/ru.json
index 5574aa9e48..832ffe8b62 100644
--- a/client/strings/ru.json
+++ b/client/strings/ru.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "Добавить {0} книг в коллекцию",
"LabelAddToPlaylist": "Добавить в плейлист",
"LabelAddToPlaylistBatch": "Добавить {0} элементов в плейлист",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "Все",
"LabelAllUsers": "Все пользователи",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Уже в Вашей библиотеке",
"LabelAppend": "Добавить",
"LabelAuthor": "Автор",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "Снять выделение",
"LabelDevice": "Устройство",
"LabelDeviceInfo": "Информация об устройстве",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "Каталог",
"LabelDiscFromFilename": "Диск из Имени файла",
"LabelDiscFromMetadata": "Диск из Метаданных",
@@ -394,6 +398,7 @@
"LabelSeason": "Сезон",
"LabelSelectAllEpisodes": "Выбрать все эпизоды",
"LabelSelectEpisodesShowing": "Выберите {0} эпизодов для показа",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "Отправить e-книгу в...",
"LabelSequence": "Последовательность",
"LabelSeries": "Серия",
diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json
index fa815fab27..5d3de27ad5 100644
--- a/client/strings/zh-cn.json
+++ b/client/strings/zh-cn.json
@@ -181,8 +181,11 @@
"LabelAddToCollectionBatch": "批量添加 {0} 个媒体到收藏",
"LabelAddToPlaylist": "添加到播放列表",
"LabelAddToPlaylistBatch": "添加 {0} 个项目到播放列表",
+ "LabelAdminUsersOnly": "Admin users only",
"LabelAll": "全部",
"LabelAllUsers": "所有用户",
+ "LabelAllUsersExcludingGuests": "All users excluding guests",
+ "LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "已存在你的库中",
"LabelAppend": "附加",
"LabelAuthor": "作者",
@@ -229,6 +232,7 @@
"LabelDeselectAll": "全部取消选择",
"LabelDevice": "设备",
"LabelDeviceInfo": "设备信息",
+ "LabelDeviceIsAvailableTo": "Device is available to...",
"LabelDirectory": "目录",
"LabelDiscFromFilename": "从文件名获取光盘",
"LabelDiscFromMetadata": "从元数据获取光盘",
@@ -394,6 +398,7 @@
"LabelSeason": "季",
"LabelSelectAllEpisodes": "选择所有剧集",
"LabelSelectEpisodesShowing": "选择正在播放的 {0} 剧集",
+ "LabelSelectUsers": "Select users",
"LabelSendEbookToDevice": "发送电子书到...",
"LabelSequence": "序列",
"LabelSeries": "系列",
diff --git a/server/controllers/EmailController.js b/server/controllers/EmailController.js
index fefc23b6c6..fcbc49054d 100644
--- a/server/controllers/EmailController.js
+++ b/server/controllers/EmailController.js
@@ -51,32 +51,45 @@ class EmailController {
})
}
+ /**
+ * Send ebook to device
+ * User must have access to device and library item
+ *
+ * @param {import('express').Request} req
+ * @param {import('express').Response} res
+ */
async sendEBookToDevice(req, res) {
- Logger.debug(`[EmailController] Send ebook to device request for libraryItemId=${req.body.libraryItemId}, deviceName=${req.body.deviceName}`)
+ Logger.debug(`[EmailController] Send ebook to device requested by user "${req.user.username}" for libraryItemId=${req.body.libraryItemId}, deviceName=${req.body.deviceName}`)
+
+ const device = Database.emailSettings.getEReaderDevice(req.body.deviceName)
+ if (!device) {
+ return res.status(404).send('Ereader device not found')
+ }
+
+ // Check user has access to device
+ if (!Database.emailSettings.checkUserCanAccessDevice(device, req.user)) {
+ return res.sendStatus(403)
+ }
const libraryItem = await Database.libraryItemModel.getOldById(req.body.libraryItemId)
if (!libraryItem) {
return res.status(404).send('Library item not found')
}
+ // Check user has access to library item
if (!req.user.checkCanAccessLibraryItem(libraryItem)) {
return res.sendStatus(403)
}
const ebookFile = libraryItem.media.ebookFile
if (!ebookFile) {
- return res.status(404).send('EBook file not found')
- }
-
- const device = Database.emailSettings.getEReaderDevice(req.body.deviceName)
- if (!device) {
- return res.status(404).send('E-reader device not found')
+ return res.status(404).send('Ebook file not found')
}
this.emailManager.sendEBookToDevice(ebookFile, device, res)
}
- middleware(req, res, next) {
+ adminMiddleware(req, res, next) {
if (!req.user.isAdminOrUp) {
return res.sendStatus(404)
}
diff --git a/server/objects/settings/EmailSettings.js b/server/objects/settings/EmailSettings.js
index 40648887b0..81e31d53d3 100644
--- a/server/objects/settings/EmailSettings.js
+++ b/server/objects/settings/EmailSettings.js
@@ -1,6 +1,14 @@
const Logger = require('../../Logger')
const { areEquivalent, copyValue, isNullOrNaN } = require('../../utils')
+/**
+ * @typedef EreaderDeviceObject
+ * @property {string} name
+ * @property {string} email
+ * @property {string} availabilityOption
+ * @property {string[]} users
+ */
+
// REF: https://nodemailer.com/smtp/
class EmailSettings {
constructor(settings = null) {
@@ -13,7 +21,7 @@ class EmailSettings {
this.testAddress = null
this.fromAddress = null
- // Array of { name:String, email:String }
+ /** @type {EreaderDeviceObject[]} */
this.ereaderDevices = []
if (settings) {
@@ -57,6 +65,26 @@ class EmailSettings {
if (payload.ereaderDevices !== undefined && !Array.isArray(payload.ereaderDevices)) payload.ereaderDevices = undefined
+ if (payload.ereaderDevices?.length) {
+ // Validate ereader devices
+ payload.ereaderDevices = payload.ereaderDevices.map((device) => {
+ if (!device.name || !device.email) {
+ Logger.error(`[EmailSettings] Update ereader device is invalid`, device)
+ return null
+ }
+ if (!device.availabilityOption || !['adminOrUp', 'userOrUp', 'guestOrUp', 'specificUsers'].includes(device.availabilityOption)) {
+ device.availabilityOption = 'adminOrUp'
+ }
+ if (device.availabilityOption === 'specificUsers' && !device.users?.length) {
+ device.availabilityOption = 'adminOrUp'
+ }
+ if (device.availabilityOption !== 'specificUsers' && device.users?.length) {
+ device.users = []
+ }
+ return device
+ }).filter(d => d)
+ }
+
let hasUpdates = false
const json = this.toJSON()
@@ -88,15 +116,40 @@ class EmailSettings {
return payload
}
- getEReaderDevices(user) {
- // Only accessible to admin or up
- if (!user.isAdminOrUp) {
- return []
+ /**
+ *
+ * @param {EreaderDeviceObject} device
+ * @param {import('../user/User')} user
+ * @returns {boolean}
+ */
+ checkUserCanAccessDevice(device, user) {
+ let deviceAvailability = device.availabilityOption || 'adminOrUp'
+ if (deviceAvailability === 'adminOrUp' && user.isAdminOrUp) return true
+ if (deviceAvailability === 'userOrUp' && (user.isAdminOrUp || user.isUser)) return true
+ if (deviceAvailability === 'guestOrUp') return true
+ if (deviceAvailability === 'specificUsers') {
+ let deviceUsers = device.users || []
+ return deviceUsers.includes(user.id)
}
+ return false
+ }
- return this.ereaderDevices.map(d => ({ ...d }))
+ /**
+ * Get ereader devices accessible to user
+ *
+ * @param {import('../user/User')} user
+ * @returns {EreaderDeviceObject[]}
+ */
+ getEReaderDevices(user) {
+ return this.ereaderDevices.filter((device) => this.checkUserCanAccessDevice(device, user))
}
+ /**
+ * Get ereader device by name
+ *
+ * @param {string} deviceName
+ * @returns {EreaderDeviceObject}
+ */
getEReaderDevice(deviceName) {
return this.ereaderDevices.find(d => d.name === deviceName)
}
diff --git a/server/objects/user/User.js b/server/objects/user/User.js
index a9c9c767b6..5192752a31 100644
--- a/server/objects/user/User.js
+++ b/server/objects/user/User.js
@@ -35,6 +35,9 @@ class User {
get isAdmin() {
return this.type === 'admin'
}
+ get isUser() {
+ return this.type === 'user'
+ }
get isGuest() {
return this.type === 'guest'
}
diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js
index 41b247165e..bb91e9b5e1 100644
--- a/server/routers/ApiRouter.js
+++ b/server/routers/ApiRouter.js
@@ -255,11 +255,11 @@ class ApiRouter {
//
// Email Routes (Admin and up)
//
- this.router.get('/emails/settings', EmailController.middleware.bind(this), EmailController.getSettings.bind(this))
- this.router.patch('/emails/settings', EmailController.middleware.bind(this), EmailController.updateSettings.bind(this))
- this.router.post('/emails/test', EmailController.middleware.bind(this), EmailController.sendTest.bind(this))
- this.router.post('/emails/ereader-devices', EmailController.middleware.bind(this), EmailController.updateEReaderDevices.bind(this))
- this.router.post('/emails/send-ebook-to-device', EmailController.middleware.bind(this), EmailController.sendEBookToDevice.bind(this))
+ this.router.get('/emails/settings', EmailController.adminMiddleware.bind(this), EmailController.getSettings.bind(this))
+ this.router.patch('/emails/settings', EmailController.adminMiddleware.bind(this), EmailController.updateSettings.bind(this))
+ this.router.post('/emails/test', EmailController.adminMiddleware.bind(this), EmailController.sendTest.bind(this))
+ this.router.post('/emails/ereader-devices', EmailController.adminMiddleware.bind(this), EmailController.updateEReaderDevices.bind(this))
+ this.router.post('/emails/send-ebook-to-device', EmailController.sendEBookToDevice.bind(this))
//
// Search Routes