diff --git a/public/language/ar/flags.json b/public/language/ar/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/ar/flags.json +++ b/public/language/ar/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/bg/flags.json b/public/language/bg/flags.json index db2ff8cfd0..acc0879d50 100644 --- a/public/language/bg/flags.json +++ b/public/language/bg/flags.json @@ -32,6 +32,9 @@ "view-profile": "Преглед на профила", "start-new-chat": "Започване на нов разговор", "go-to-target": "Преглед на целта на доклада", + "delete-post": "Изтриване на публикацията", + "purge-post": "Изчистване на публикацията", + "restore-post": "Възстановяване на публикацията", "user-view": "Преглед на профила", "user-edit": "Редактиране на профила", diff --git a/public/language/bn/flags.json b/public/language/bn/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/bn/flags.json +++ b/public/language/bn/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/cs/flags.json b/public/language/cs/flags.json index dba3363c64..c780e8095d 100644 --- a/public/language/cs/flags.json +++ b/public/language/cs/flags.json @@ -32,6 +32,9 @@ "view-profile": "Zobrazit profil", "start-new-chat": "Začít novou konverzaci", "go-to-target": "Zobrazit cílové označení", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Zobrazit profil", "user-edit": "Upravit profil", diff --git a/public/language/da/flags.json b/public/language/da/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/da/flags.json +++ b/public/language/da/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/de/flags.json b/public/language/de/flags.json index dca0964dbd..8eaf073b8f 100644 --- a/public/language/de/flags.json +++ b/public/language/de/flags.json @@ -32,6 +32,9 @@ "view-profile": "Profil ansehen", "start-new-chat": "Neuen Chat beginnen", "go-to-target": "Meldungsziel ansehen", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Profil ansehen", "user-edit": "Profil bearbeiten", diff --git a/public/language/el/flags.json b/public/language/el/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/el/flags.json +++ b/public/language/el/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/en-US/flags.json b/public/language/en-US/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/en-US/flags.json +++ b/public/language/en-US/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/en-x-pirate/flags.json b/public/language/en-x-pirate/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/en-x-pirate/flags.json +++ b/public/language/en-x-pirate/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/es/flags.json b/public/language/es/flags.json index bd108630a8..a91a35ed93 100644 --- a/public/language/es/flags.json +++ b/public/language/es/flags.json @@ -32,6 +32,9 @@ "view-profile": "Ver perfil", "start-new-chat": "Empezar nuevo chat", "go-to-target": "Ver objetivo marcado", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Ver perfil", "user-edit": "Editar perfil", diff --git a/public/language/et/flags.json b/public/language/et/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/et/flags.json +++ b/public/language/et/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/fa-IR/flags.json b/public/language/fa-IR/flags.json index 7c908db76c..203807dfeb 100644 --- a/public/language/fa-IR/flags.json +++ b/public/language/fa-IR/flags.json @@ -32,6 +32,9 @@ "view-profile": "نمایش پروفایل", "start-new-chat": "شروع چت جدید", "go-to-target": "مشاهده محتوای گزارش شده", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "نمایش پروفایل", "user-edit": "ویرایش پروفایل", diff --git a/public/language/fi/flags.json b/public/language/fi/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/fi/flags.json +++ b/public/language/fi/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/fr/flags.json b/public/language/fr/flags.json index 36d788a4e7..12de8b62c0 100644 --- a/public/language/fr/flags.json +++ b/public/language/fr/flags.json @@ -32,6 +32,9 @@ "view-profile": "Voir le profil", "start-new-chat": "Démarrer un nouveau Chat", "go-to-target": "Voir le signalement cible", + "delete-post": "Supprimer les messages", + "purge-post": "Supprimer définitivement", + "restore-post": "Restaurer les messages", "user-view": "Voir le profil", "user-edit": "Éditer le profil", diff --git a/public/language/gl/flags.json b/public/language/gl/flags.json index 0996704e0a..52250c1ef2 100644 --- a/public/language/gl/flags.json +++ b/public/language/gl/flags.json @@ -32,6 +32,9 @@ "view-profile": "Ver perfil", "start-new-chat": "Comezar novo chat", "go-to-target": "Ver contido marcado", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Ver perfil", "user-edit": "Editar perfil", diff --git a/public/language/he/flags.json b/public/language/he/flags.json index 450d66d0cb..6f3760b830 100644 --- a/public/language/he/flags.json +++ b/public/language/he/flags.json @@ -32,6 +32,9 @@ "view-profile": "צפה בפרופיל", "start-new-chat": "התחל שיחה חדשה", "go-to-target": "צפה במטרת הסימון", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "צפה בפרופיל", "user-edit": "ערוך פרופיל", diff --git a/public/language/hr/flags.json b/public/language/hr/flags.json index 514d5cd9d3..f8305b59f7 100644 --- a/public/language/hr/flags.json +++ b/public/language/hr/flags.json @@ -32,6 +32,9 @@ "view-profile": "Pogledaj profil", "start-new-chat": "Pokreni novi razgovor", "go-to-target": "Pogledaj metu zastave", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Pogledaj profil", "user-edit": "Uredi profil", diff --git a/public/language/hu/flags.json b/public/language/hu/flags.json index 960922c9ac..fc29212f5d 100644 --- a/public/language/hu/flags.json +++ b/public/language/hu/flags.json @@ -32,6 +32,9 @@ "view-profile": "Profil megtekintése", "start-new-chat": "Új chat indítása", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/id/flags.json b/public/language/id/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/id/flags.json +++ b/public/language/id/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/it/flags.json b/public/language/it/flags.json index ae70cd7d9c..49b2ebd58e 100644 --- a/public/language/it/flags.json +++ b/public/language/it/flags.json @@ -32,6 +32,9 @@ "view-profile": "Vedi Profilo", "start-new-chat": "Inizia Nuova Chat", "go-to-target": "Visualizza oggetto segnalazione", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Vedi Profilo", "user-edit": "Modifica Profilo", diff --git a/public/language/ja/flags.json b/public/language/ja/flags.json index c3a4694768..3aba386186 100644 --- a/public/language/ja/flags.json +++ b/public/language/ja/flags.json @@ -32,6 +32,9 @@ "view-profile": "プロフィールを見る", "start-new-chat": "新しいチャットを開始", "go-to-target": "フラグのターゲットを表示", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "プロフィールを見る", "user-edit": "プロフィールを編集", diff --git a/public/language/ko/flags.json b/public/language/ko/flags.json index 7ab24f8a62..5bbdb89def 100644 --- a/public/language/ko/flags.json +++ b/public/language/ko/flags.json @@ -32,6 +32,9 @@ "view-profile": "프로필 보기", "start-new-chat": "새로운 채팅 시작", "go-to-target": "신고된 게시물 바로가기", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "프로필 보기", "user-edit": "프로필 수정", diff --git a/public/language/lt/flags.json b/public/language/lt/flags.json index 55091fa437..105f338f53 100644 --- a/public/language/lt/flags.json +++ b/public/language/lt/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/lv/flags.json b/public/language/lv/flags.json index 74b1352881..5a656e0bac 100644 --- a/public/language/lv/flags.json +++ b/public/language/lv/flags.json @@ -32,6 +32,9 @@ "view-profile": "Skatīt profilu", "start-new-chat": "Sākt jaunu sarunu", "go-to-target": "Skatīt atzīmēto rakstu", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Skatīt profilu", "user-edit": "Rediģēt profilu", diff --git a/public/language/ms/flags.json b/public/language/ms/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/ms/flags.json +++ b/public/language/ms/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/nb/flags.json b/public/language/nb/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/nb/flags.json +++ b/public/language/nb/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/nl/flags.json b/public/language/nl/flags.json index 2ce9c901a3..976f605e86 100644 --- a/public/language/nl/flags.json +++ b/public/language/nl/flags.json @@ -32,6 +32,9 @@ "view-profile": "Profiel bekijken", "start-new-chat": "Begin een nieuwe chat", "go-to-target": "Bekijk markering doel", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Profiel bekijken", "user-edit": "Profiel wijzigen", diff --git a/public/language/pl/flags.json b/public/language/pl/flags.json index a5ecb50ba8..f1e44db6c6 100644 --- a/public/language/pl/flags.json +++ b/public/language/pl/flags.json @@ -32,6 +32,9 @@ "view-profile": "Zobacz profil", "start-new-chat": "Rozpocznij nowy czat", "go-to-target": "Zobacz cel flagowania", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Zobacz profil", "user-edit": "Edytuj profil", diff --git a/public/language/pt-BR/flags.json b/public/language/pt-BR/flags.json index 682fb1036f..11340c2fba 100644 --- a/public/language/pt-BR/flags.json +++ b/public/language/pt-BR/flags.json @@ -32,6 +32,9 @@ "view-profile": "Ver Perfil", "start-new-chat": "Iniciar Novo Chat", "go-to-target": "Ver o Sinalizado", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Ver Perfil", "user-edit": "Editar Perfil", diff --git a/public/language/pt-PT/flags.json b/public/language/pt-PT/flags.json index 10605b93b3..a0124d1546 100644 --- a/public/language/pt-PT/flags.json +++ b/public/language/pt-PT/flags.json @@ -32,6 +32,9 @@ "view-profile": "Ver Perfil", "start-new-chat": "Iniciar Nova Conversa", "go-to-target": "Ver Alvo da Denúncia", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Ver Perfil", "user-edit": "Editar Perfil", diff --git a/public/language/ro/flags.json b/public/language/ro/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/ro/flags.json +++ b/public/language/ro/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/ru/flags.json b/public/language/ru/flags.json index 8d6c5c8508..6c12efdf73 100644 --- a/public/language/ru/flags.json +++ b/public/language/ru/flags.json @@ -32,6 +32,9 @@ "view-profile": "Просмотреть профиль", "start-new-chat": "Начать новый чат", "go-to-target": "Показать предмет жалобы", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Открыть профиль", "user-edit": "Изменить профиль", diff --git a/public/language/rw/flags.json b/public/language/rw/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/rw/flags.json +++ b/public/language/rw/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/sc/flags.json b/public/language/sc/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/sc/flags.json +++ b/public/language/sc/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/sk/flags.json b/public/language/sk/flags.json index f078277497..5d806b2769 100644 --- a/public/language/sk/flags.json +++ b/public/language/sk/flags.json @@ -32,6 +32,9 @@ "view-profile": "Zobraziť profil", "start-new-chat": "Začať novú konverzáciu", "go-to-target": "Zobraziť cieľové označenie", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Zobraziť profil", "user-edit": "Upraviť profil", diff --git a/public/language/sl/flags.json b/public/language/sl/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/sl/flags.json +++ b/public/language/sl/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/sr/flags.json b/public/language/sr/flags.json index 7cdbd98234..1bb26a6712 100644 --- a/public/language/sr/flags.json +++ b/public/language/sr/flags.json @@ -32,6 +32,9 @@ "view-profile": "Погледај профил", "start-new-chat": "Започни ново ћаскање", "go-to-target": "Погледај циљ означавања", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Погледај профил", "user-edit": "Уреди профил", diff --git a/public/language/sv/flags.json b/public/language/sv/flags.json index 1d5e75ddfe..0612b51909 100644 --- a/public/language/sv/flags.json +++ b/public/language/sv/flags.json @@ -32,6 +32,9 @@ "view-profile": "Visa profil", "start-new-chat": "Påbörja ny chatt", "go-to-target": "Visa flaggans ämne", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Visa profil", "user-edit": "Redigera profil", diff --git a/public/language/th/flags.json b/public/language/th/flags.json index d5dcacaf85..81791d0bce 100644 --- a/public/language/th/flags.json +++ b/public/language/th/flags.json @@ -32,6 +32,9 @@ "view-profile": "ดูโปรไฟล์", "start-new-chat": "เริ่มแชทใหม่", "go-to-target": "ดูเป้าหมายการปักธง", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "ดูโปรไฟล์", "user-edit": "แก้ไขโปรไฟล์", diff --git a/public/language/tr/flags.json b/public/language/tr/flags.json index 050acef1f6..2a36c90680 100644 --- a/public/language/tr/flags.json +++ b/public/language/tr/flags.json @@ -32,6 +32,9 @@ "view-profile": "Profili Gör", "start-new-chat": "Yeni Sohbet Başlat", "go-to-target": "Şikayet Edilen İçeriği Gör", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "Profili Gör", "user-edit": "Profili Düzenle", diff --git a/public/language/vi/flags.json b/public/language/vi/flags.json index 09b0fe746d..649d3878d1 100644 --- a/public/language/vi/flags.json +++ b/public/language/vi/flags.json @@ -32,6 +32,9 @@ "view-profile": "View Profile", "start-new-chat": "Start New Chat", "go-to-target": "View Flag Target", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "View Profile", "user-edit": "Edit Profile", diff --git a/public/language/zh-CN/flags.json b/public/language/zh-CN/flags.json index 6db9a6f765..7e6cc155e6 100644 --- a/public/language/zh-CN/flags.json +++ b/public/language/zh-CN/flags.json @@ -32,6 +32,9 @@ "view-profile": "查看个人资料", "start-new-chat": "开始新会话", "go-to-target": "查看举报目标", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "查看资料", "user-edit": "编辑资料", diff --git a/public/language/zh-TW/flags.json b/public/language/zh-TW/flags.json index f09087641a..234ffc735f 100644 --- a/public/language/zh-TW/flags.json +++ b/public/language/zh-TW/flags.json @@ -32,6 +32,9 @@ "view-profile": "查看個人資料", "start-new-chat": "開始新聊天對話", "go-to-target": "查看舉報目標", + "delete-post": "Delete Post", + "purge-post": "Purge Post", + "restore-post": "Restore Post", "user-view": "查看資料", "user-edit": "編輯資料", diff --git a/public/src/modules/search.js b/public/src/modules/search.js index b653890bf9..3b89d5dad9 100644 --- a/public/src/modules/search.js +++ b/public/src/modules/search.js @@ -36,7 +36,7 @@ define('search', ['navigator', 'translator', 'storage'], function (nav, translat Search.quick = function (query, options, callback) { callback = callback || function () {}; var template = options.template || 'partials/quick-search-results'; - $(window).trigger('action:search.quick', { data: query }); + $(window).trigger('action:search.quick.start', { data: query }); query.searchOnly = 1; Search.api(query, function (data) { if (options.hideOnNoMatches && !data.posts.length) { @@ -52,7 +52,7 @@ define('search', ['navigator', 'translator', 'storage'], function (nav, translat } else { options.resultEl.addClass('hidden').find('#quick-search-results-container').html(''); } - $(window).trigger('action:search.quick.complete', { }); + $(window).trigger('action:search.quick.complete', { data: data }); callback(); }); }); diff --git a/src/analytics.js b/src/analytics.js index 914a579fa9..3db38cba27 100644 --- a/src/analytics.js +++ b/src/analytics.js @@ -52,7 +52,7 @@ Analytics.increment = function (keys, callback) { } }; -Analytics.pageView = function (payload) { +Analytics.pageView = async function (payload) { pageViews += 1; if (payload.uid > 0) { @@ -71,20 +71,16 @@ Analytics.pageView = function (payload) { ipCache.set(payload.ip + nconf.get('secret'), hash); } - db.sortedSetScore('ip:recent', hash, function (err, score) { - if (err) { - return; - } - if (!score) { - uniqueIPCount += 1; - } - var today = new Date(); - today.setHours(today.getHours(), 0, 0, 0); - if (!score || score < today.getTime()) { - uniquevisitors += 1; - db.sortedSetAdd('ip:recent', Date.now(), hash); - } - }); + const score = await db.sortedSetScore('ip:recent', hash); + if (!score) { + uniqueIPCount += 1; + } + const today = new Date(); + today.setHours(today.getHours(), 0, 0, 0); + if (!score || score < today.getTime()) { + uniquevisitors += 1; + await db.sortedSetAdd('ip:recent', Date.now(), hash); + } } }; diff --git a/src/controllers/404.js b/src/controllers/404.js index c1d6578d68..3e93c4ac32 100644 --- a/src/controllers/404.js +++ b/src/controllers/404.js @@ -6,6 +6,7 @@ const validator = require('validator'); const meta = require('../meta'); const plugins = require('../plugins'); +const middleware = require('../middleware'); exports.handle404 = function handle404(req, res) { const relativePath = nconf.get('relative_path'); @@ -36,14 +37,12 @@ exports.handle404 = function handle404(req, res) { } }; -exports.send404 = function (req, res) { +exports.send404 = async function (req, res) { res.status(404); const path = String(req.path || ''); if (res.locals.isAPI) { return res.json({ path: validator.escape(path.replace(/^\/api/, '')), title: '[[global:404.title]]' }); } - const middleware = require('../middleware'); - middleware.buildHeader(req, res, function () { - res.render('404', { path: validator.escape(path), title: '[[global:404.title]]' }); - }); + await middleware.buildHeaderAsync(req, res); + res.render('404', { path: validator.escape(path), title: '[[global:404.title]]' }); }; diff --git a/src/controllers/errors.js b/src/controllers/errors.js index 0000b36b9b..2052952067 100644 --- a/src/controllers/errors.js +++ b/src/controllers/errors.js @@ -4,8 +4,9 @@ var nconf = require('nconf'); var winston = require('winston'); var validator = require('validator'); var plugins = require('../plugins'); +var middleware = require('../middleware'); -exports.handleURIErrors = function handleURIErrors(err, req, res, next) { +exports.handleURIErrors = async function handleURIErrors(err, req, res, next) { // Handle cases where malformed URIs are passed in if (err instanceof URIError) { const cleanPath = req.path.replace(new RegExp('^' + nconf.get('relative_path')), ''); @@ -23,10 +24,8 @@ exports.handleURIErrors = function handleURIErrors(err, req, res, next) { error: '[[global:400.title]]', }); } else { - var middleware = require('../middleware'); - middleware.buildHeader(req, res, function () { - res.status(400).render('400', { error: validator.escape(String(err.message)) }); - }); + await middleware.buildHeaderAsync(req, res); + res.status(400).render('400', { error: validator.escape(String(err.message)) }); } } } else { @@ -46,7 +45,7 @@ exports.handleErrors = function handleErrors(err, req, res, next) { // eslint-di res.status(403).type('text/plain').send(err.message); }, }; - var defaultHandler = function () { + var defaultHandler = async function () { // Display NodeBB error page var status = parseInt(err.status, 10); if ((status === 302 || status === 308) && err.path) { @@ -61,10 +60,8 @@ exports.handleErrors = function handleErrors(err, req, res, next) { // eslint-di if (res.locals.isAPI) { res.json({ path: validator.escape(path), error: err.message }); } else { - var middleware = require('../middleware'); - middleware.buildHeader(req, res, function () { - res.render('500', { path: validator.escape(path), error: validator.escape(String(err.message)) }); - }); + await middleware.buildHeaderAsync(req, res); + res.render('500', { path: validator.escape(path), error: validator.escape(String(err.message)) }); } }; diff --git a/src/controllers/helpers.js b/src/controllers/helpers.js index 8ce5811cf0..1d3a5ff424 100644 --- a/src/controllers/helpers.js +++ b/src/controllers/helpers.js @@ -2,7 +2,6 @@ const nconf = require('nconf'); const validator = require('validator'); -const winston = require('winston'); const querystring = require('querystring'); const _ = require('lodash'); @@ -15,21 +14,19 @@ const middleware = require('../middleware'); const helpers = module.exports; -helpers.noScriptErrors = function (req, res, error, httpStatus) { +helpers.noScriptErrors = async function (req, res, error, httpStatus) { if (req.body.noscript !== 'true') { return res.status(httpStatus).send(error); } - const middleware = require('../middleware'); const httpStatusString = httpStatus.toString(); - middleware.buildHeader(req, res, function () { - res.status(httpStatus).render(httpStatusString, { - path: req.path, - loggedIn: req.loggedIn, - error: error, - returnLink: true, - title: '[[global:' + httpStatusString + '.title]]', - }); + await middleware.buildHeaderAsync(req, res); + res.status(httpStatus).render(httpStatusString, { + path: req.path, + loggedIn: req.loggedIn, + error: error, + returnLink: true, + title: '[[global:' + httpStatusString + '.title]]', }); }; @@ -104,41 +101,37 @@ helpers.buildTerms = function (url, term, query) { }]; }; -helpers.notAllowed = function (req, res, error) { - plugins.fireHook('filter:helpers.notAllowed', { +helpers.notAllowed = async function (req, res, error) { + const data = await plugins.fireHook('filter:helpers.notAllowed', { req: req, res: res, error: error, - }, function (err) { - if (err) { - return winston.error(err); - } - if (req.loggedIn || req.uid === -1) { - if (res.locals.isAPI) { - res.status(403).json({ - path: req.path.replace(/^\/api/, ''), - loggedIn: req.loggedIn, - error: error, - title: '[[global:403.title]]', - }); - } else { - middleware.buildHeader(req, res, function () { - res.status(403).render('403', { - path: req.path, - loggedIn: req.loggedIn, - error: error, - title: '[[global:403.title]]', - }); - }); - } - } else if (res.locals.isAPI) { - req.session.returnTo = req.url.replace(/^\/api/, ''); - res.status(401).json('not-authorized'); - } else { - req.session.returnTo = req.url; - res.redirect(nconf.get('relative_path') + '/login'); - } }); + + if (req.loggedIn || req.uid === -1) { + if (res.locals.isAPI) { + res.status(403).json({ + path: req.path.replace(/^\/api/, ''), + loggedIn: req.loggedIn, + error: data.error, + title: '[[global:403.title]]', + }); + } else { + await middleware.buildHeaderAsync(req, res); + res.status(403).render('403', { + path: req.path, + loggedIn: req.loggedIn, + error: data.error, + title: '[[global:403.title]]', + }); + } + } else if (res.locals.isAPI) { + req.session.returnTo = req.url.replace(/^\/api/, ''); + res.status(401).json('not-authorized'); + } else { + req.session.returnTo = req.url; + res.redirect(nconf.get('relative_path') + '/login'); + } }; helpers.redirect = function (res, url) { diff --git a/src/middleware/admin.js b/src/middleware/admin.js index bb1e83dc30..33e8a45f49 100644 --- a/src/middleware/admin.js +++ b/src/middleware/admin.js @@ -1,6 +1,5 @@ 'use strict'; -var async = require('async'); var winston = require('winston'); var jsesc = require('jsesc'); var nconf = require('nconf'); @@ -9,7 +8,9 @@ var semver = require('semver'); var user = require('../user'); var meta = require('../meta'); var plugins = require('../plugins'); +var utils = require('../../public/src/utils'); var versions = require('../admin/versions'); +var helpers = require('./helpers'); var controllers = { api: require('../controllers/api'), @@ -18,112 +19,88 @@ var controllers = { module.exports = function (middleware) { middleware.admin = {}; - middleware.admin.isAdmin = function (req, res, next) { + middleware.admin.isAdmin = helpers.try(async function (req, res, next) { winston.warn('[middleware.admin.isAdmin] deprecation warning, no need to use this from plugins!'); - middleware.isAdmin(req, res, next); - }; + await middleware.isAdmin(req, res, next); + }); - middleware.admin.buildHeader = function (req, res, next) { + middleware.admin.buildHeader = helpers.try(async function (req, res, next) { res.locals.renderAdminHeader = true; + res.locals.config = await controllers.api.loadConfig(req); + next(); + }); - async.waterfall([ - function (next) { - controllers.api.loadConfig(req, next); - }, - function (config, next) { - res.locals.config = config; - next(); - }, - ], next); - }; - - middleware.admin.renderHeader = function (req, res, data, next) { + middleware.admin.renderHeader = async (req, res, data) => { var custom_header = { plugins: [], authentication: [], }; res.locals.config = res.locals.config || {}; - async.waterfall([ - function (next) { - async.parallel({ - userData: function (next) { - user.getUserFields(req.uid, ['username', 'userslug', 'email', 'picture', 'email:confirmed'], next); - }, - scripts: function (next) { - getAdminScripts(next); - }, - custom_header: function (next) { - plugins.fireHook('filter:admin.header.build', custom_header, next); - }, - configs: function (next) { - meta.configs.list(next); - }, - latestVersion: function (next) { - versions.getLatestVersion(function (err, result) { - if (err) { - winston.error('[acp] Failed to fetch latest version', err); - } - next(null, err ? null : result); - }); - }, - }, next); - }, - function (results, next) { - var userData = results.userData; - userData.uid = req.uid; - userData['email:confirmed'] = userData['email:confirmed'] === 1; + const results = await utils.promiseParallel({ + userData: user.getUserFields(req.uid, ['username', 'userslug', 'email', 'picture', 'email:confirmed']), + scripts: getAdminScripts(), + custom_header: plugins.fireHook('filter:admin.header.build', custom_header), + configs: meta.configs.list(), + latestVersion: getLatestVersion(), + }); - var acpPath = req.path.slice(1).split('/'); - acpPath.forEach(function (path, i) { - acpPath[i] = path.charAt(0).toUpperCase() + path.slice(1); - }); - acpPath = acpPath.join(' > '); + var userData = results.userData; + userData.uid = req.uid; + userData['email:confirmed'] = userData['email:confirmed'] === 1; - var version = nconf.get('version'); + var acpPath = req.path.slice(1).split('/'); + acpPath.forEach(function (path, i) { + acpPath[i] = path.charAt(0).toUpperCase() + path.slice(1); + }); + acpPath = acpPath.join(' > '); - res.locals.config.userLang = res.locals.config.acpLang || res.locals.config.userLang; - var templateValues = { - config: res.locals.config, - configJSON: jsesc(JSON.stringify(res.locals.config), { isScriptContext: true }), - relative_path: res.locals.config.relative_path, - adminConfigJSON: encodeURIComponent(JSON.stringify(results.configs)), - user: userData, - userJSON: jsesc(JSON.stringify(userData), { isScriptContext: true }), - plugins: results.custom_header.plugins, - authentication: results.custom_header.authentication, - scripts: results.scripts, - 'cache-buster': meta.config['cache-buster'] || '', - env: !!process.env.NODE_ENV, - title: (acpPath || 'Dashboard') + ' | NodeBB Admin Control Panel', - bodyClass: data.bodyClass, - version: version, - latestVersion: results.latestVersion, - upgradeAvailable: results.latestVersion && semver.gt(results.latestVersion, version), - }; + var version = nconf.get('version'); - templateValues.template = { name: res.locals.template }; - templateValues.template[res.locals.template] = true; + res.locals.config.userLang = res.locals.config.acpLang || res.locals.config.userLang; + var templateValues = { + config: res.locals.config, + configJSON: jsesc(JSON.stringify(res.locals.config), { isScriptContext: true }), + relative_path: res.locals.config.relative_path, + adminConfigJSON: encodeURIComponent(JSON.stringify(results.configs)), + user: userData, + userJSON: jsesc(JSON.stringify(userData), { isScriptContext: true }), + plugins: results.custom_header.plugins, + authentication: results.custom_header.authentication, + scripts: results.scripts, + 'cache-buster': meta.config['cache-buster'] || '', + env: !!process.env.NODE_ENV, + title: (acpPath || 'Dashboard') + ' | NodeBB Admin Control Panel', + bodyClass: data.bodyClass, + version: version, + latestVersion: results.latestVersion, + upgradeAvailable: results.latestVersion && semver.gt(results.latestVersion, version), + }; - req.app.render('admin/header', templateValues, next); - }, - ], next); + templateValues.template = { name: res.locals.template }; + templateValues.template[res.locals.template] = true; + + return await req.app.renderAsync('admin/header', templateValues); }; - function getAdminScripts(callback) { - async.waterfall([ - function (next) { - plugins.fireHook('filter:admin.scripts.get', [], next); - }, - function (scripts, next) { - next(null, scripts.map(function (script) { - return { src: script }; - })); - }, - ], callback); + async function getAdminScripts() { + const scripts = await plugins.fireHook('filter:admin.scripts.get', []); + return scripts.map(function (script) { + return { src: script }; + }); } - middleware.admin.renderFooter = function (req, res, data, next) { - req.app.render('admin/footer', data, next); + async function getLatestVersion() { + try { + const result = await versions.getLatestVersion(); + return result; + } catch (err) { + winston.error('[acp] Failed to fetch latest version' + err.stack); + } + return null; + } + + middleware.admin.renderFooter = async function (req, res, data) { + return await req.app.renderAsync('admin/footer', data); }; }; diff --git a/src/middleware/header.js b/src/middleware/header.js index 6963a06565..ea208895ab 100644 --- a/src/middleware/header.js +++ b/src/middleware/header.js @@ -1,9 +1,9 @@ 'use strict'; -var async = require('async'); var nconf = require('nconf'); var jsesc = require('jsesc'); var _ = require('lodash'); +var util = require('util'); var db = require('../database'); var user = require('../user'); @@ -16,6 +16,7 @@ var translator = require('../translator'); var privileges = require('../privileges'); var languages = require('../languages'); var utils = require('../utils'); +var helpers = require('./helpers'); var controllers = { api: require('../controllers/api'), @@ -23,36 +24,20 @@ var controllers = { }; module.exports = function (middleware) { - middleware.buildHeader = function buildHeader(req, res, next) { + middleware.buildHeader = helpers.try(async function buildHeader(req, res, next) { res.locals.renderHeader = true; res.locals.isAPI = false; - async.waterfall([ - function (next) { - if (req.uid >= 0) { - middleware.applyCSRF(req, res, next); - } else { - setImmediate(next); - } - }, - function (next) { - async.parallel({ - config: function (next) { - controllers.api.loadConfig(req, next); - }, - plugins: function (next) { - plugins.fireHook('filter:middleware.buildHeader', { req: req, locals: res.locals }, next); - }, - }, next); - }, - function (results, next) { - res.locals.config = results.config; - // Return no arguments - setImmediate(next); - }, - ], next); - }; + const [config] = await Promise.all([ + controllers.api.loadConfig(req), + plugins.fireHook('filter:middleware.buildHeader', { req: req, locals: res.locals }), + ]); + res.locals.config = config; + next(); + }); - middleware.generateHeader = function generateHeader(req, res, data, callback) { + middleware.buildHeaderAsync = util.promisify(middleware.buildHeader); + + async function generateHeader(req, res, data) { var registrationType = meta.config.registrationType || 'normal'; res.locals.config = res.locals.config || {}; var templateValues = { @@ -73,207 +58,162 @@ module.exports = function (middleware) { templateValues.configJSON = jsesc(JSON.stringify(res.locals.config), { isScriptContext: true }); - async.waterfall([ - function (next) { - async.parallel({ - isAdmin: function (next) { - user.isAdministrator(req.uid, next); - }, - isGlobalMod: function (next) { - user.isGlobalModerator(req.uid, next); - }, - isModerator: function (next) { - user.isModeratorOfAnyCategory(req.uid, next); - }, - privileges: function (next) { - privileges.global.get(req.uid, next); - }, - user: function (next) { - user.getUserData(req.uid, next); - }, - isEmailConfirmSent: function (next) { - if (!meta.config.requireEmailConfirmation || req.uid <= 0) { - return next(null, false); - } - db.get('uid:' + req.uid + ':confirm:email:sent', next); - }, - languageDirection: function (next) { - translator.translate('[[language:dir]]', res.locals.config.userLang, function (translated) { - next(null, translated); - }); - }, - browserTitle: function (next) { - translator.translate(controllers.helpers.buildTitle(translator.unescape(data.title)), function (translated) { - next(null, translated); - }); - }, - navigation: async.apply(navigation.get, req.uid), - banned: async.apply(user.bans.isBanned, req.uid), - banReason: async.apply(user.bans.getReason, req.uid), + const results = await utils.promiseParallel({ + isAdmin: user.isAdministrator(req.uid), + isGlobalMod: user.isGlobalModerator(req.uid), + isModerator: user.isModeratorOfAnyCategory(req.uid), + privileges: privileges.global.get(req.uid), + user: user.getUserData(req.uid), + isEmailConfirmSent: (!meta.config.requireEmailConfirmation || req.uid <= 0) ? false : await db.get('uid:' + req.uid + ':confirm:email:sent'), + languageDirection: translator.translate('[[language:dir]]', res.locals.config.userLang), + browserTitle: translator.translate(controllers.helpers.buildTitle(translator.unescape(data.title))), + navigation: navigation.get(req.uid), + banned: user.bans.isBanned(req.uid), + banReason: user.bans.getReason(req.uid), - unreadData: async.apply(topics.getUnreadData, { uid: req.uid }), - unreadChatCount: async.apply(messaging.getUnreadCount, req.uid), - unreadNotificationCount: async.apply(user.notifications.getUnreadCount, req.uid), - }, next); - }, - function (results, next) { - if (results.banned) { - req.logout(); - return res.redirect('/'); - } - - const unreadData = { - '': {}, - new: {}, - watched: {}, - unreplied: {}, - }; - - results.user.unreadData = unreadData; - results.user.isAdmin = results.isAdmin; - results.user.isGlobalMod = results.isGlobalMod; - results.user.isMod = !!results.isModerator; - results.user.privileges = results.privileges; - results.user[results.user.status] = true; - - results.user.email = String(results.user.email); - results.user['email:confirmed'] = results.user['email:confirmed'] === 1; - results.user.isEmailConfirmSent = !!results.isEmailConfirmSent; - - templateValues.bootswatchSkin = (parseInt(meta.config.disableCustomUserSkins, 10) !== 1 ? res.locals.config.bootswatchSkin : '') || meta.config.bootswatchSkin || ''; - templateValues.config.bootswatchSkin = templateValues.bootswatchSkin || 'noskin'; // TODO remove in v1.12.0+ - - const unreadCounts = results.unreadData.counts; - var unreadCount = { - topic: unreadCounts[''] || 0, - newTopic: unreadCounts.new || 0, - watchedTopic: unreadCounts.watched || 0, - unrepliedTopic: unreadCounts.unreplied || 0, - chat: results.unreadChatCount || 0, - notification: results.unreadNotificationCount || 0, - }; - - Object.keys(unreadCount).forEach(function (key) { - if (unreadCount[key] > 99) { - unreadCount[key] = '99+'; - } - }); - - const tidsByFilter = results.unreadData.tidsByFilter; - results.navigation = results.navigation.map(function (item) { - function modifyNavItem(item, route, filter, content) { - if (item && item.originalRoute === route) { - unreadData[filter] = _.zipObject(tidsByFilter[filter], tidsByFilter[filter].map(() => true)); - item.content = content; - if (unreadCounts[filter] > 0) { - item.iconClass += ' unread-count'; - } - } - } - modifyNavItem(item, '/unread', '', unreadCount.topic); - modifyNavItem(item, '/unread?filter=new', 'new', unreadCount.newTopic); - modifyNavItem(item, '/unread?filter=watched', 'watched', unreadCount.watchedTopic); - modifyNavItem(item, '/unread?filter=unreplied', 'unreplied', unreadCount.unrepliedTopic); - return item; - }); - - templateValues.browserTitle = results.browserTitle; - templateValues.navigation = results.navigation; - templateValues.unreadCount = unreadCount; - templateValues.isAdmin = results.user.isAdmin; - templateValues.isGlobalMod = results.user.isGlobalMod; - templateValues.showModMenu = results.user.isAdmin || results.user.isGlobalMod || results.user.isMod; - templateValues.canChat = results.canChat && meta.config.disableChat !== 1; - templateValues.user = results.user; - templateValues.userJSON = jsesc(JSON.stringify(results.user), { isScriptContext: true }); - templateValues.useCustomCSS = meta.config.useCustomCSS && meta.config.customCSS; - templateValues.customCSS = templateValues.useCustomCSS ? (meta.config.renderedCustomCSS || '') : ''; - templateValues.useCustomHTML = meta.config.useCustomHTML; - templateValues.customHTML = templateValues.useCustomHTML ? meta.config.customHTML : ''; - templateValues.maintenanceHeader = meta.config.maintenanceMode && !results.isAdmin; - templateValues.defaultLang = meta.config.defaultLang || 'en-GB'; - templateValues.userLang = res.locals.config.userLang; - templateValues.languageDirection = results.languageDirection; - - templateValues.template = { name: res.locals.template }; - templateValues.template[res.locals.template] = true; - - if (data.hasOwnProperty('_header')) { - templateValues.metaTags = data._header.tags.meta; - templateValues.linkTags = data._header.tags.link; - } - - if (req.route && req.route.path === '/') { - modifyTitle(templateValues); - } - - plugins.fireHook('filter:middleware.renderHeader', { - req: req, - res: res, - templateValues: templateValues, - data: data, - }, next); - }, - ], function (err, data) { - callback(err, data.templateValues); + unreadData: topics.getUnreadData({ uid: req.uid }), + unreadChatCount: messaging.getUnreadCount(req.uid), + unreadNotificationCount: user.notifications.getUnreadCount(req.uid), }); - }; - middleware.renderHeader = function renderHeader(req, res, data, callback) { - async.waterfall([ - async.apply(middleware.generateHeader, req, res, data), - function (templateValues, next) { - req.app.render('header', templateValues, next); - }, - ], callback); - }; + if (results.banned) { + req.logout(); + return res.redirect('/'); + } - middleware.renderFooter = function renderFooter(req, res, data, callback) { - async.waterfall([ - function (next) { - plugins.fireHook('filter:middleware.renderFooter', { - req: req, - res: res, - templateValues: data, - }, next); - }, - function (data, next) { - async.parallel({ - scripts: async.apply(plugins.fireHook, 'filter:scripts.get', []), - timeagoLocale: (next) => { - async.waterfall([ - async.apply(languages.listCodes), - (languageCodes, next) => { - const userLang = res.locals.config.userLang; - const timeagoCode = utils.userLangToTimeagoCode(userLang); + const unreadData = { + '': {}, + new: {}, + watched: {}, + unreplied: {}, + }; - if (languageCodes.includes(userLang) && languages.timeagoCodes.includes(timeagoCode)) { - const pathToLocaleFile = '/vendor/jquery/timeago/locales/jquery.timeago.' + timeagoCode + '.js'; - next(null, (nconf.get('relative_path') + '/assets' + pathToLocaleFile)); - } else { - next(null, false); - } - }, - ], next); - }, - }, function (err, results) { - next(err, data, results); - }); - }, - function (data, results, next) { - if (results.timeagoLocale) { - results.scripts.push(results.timeagoLocale); + results.user.unreadData = unreadData; + results.user.isAdmin = results.isAdmin; + results.user.isGlobalMod = results.isGlobalMod; + results.user.isMod = !!results.isModerator; + results.user.privileges = results.privileges; + results.user[results.user.status] = true; + + results.user.email = String(results.user.email); + results.user['email:confirmed'] = results.user['email:confirmed'] === 1; + results.user.isEmailConfirmSent = !!results.isEmailConfirmSent; + + templateValues.bootswatchSkin = (parseInt(meta.config.disableCustomUserSkins, 10) !== 1 ? res.locals.config.bootswatchSkin : '') || meta.config.bootswatchSkin || ''; + templateValues.config.bootswatchSkin = templateValues.bootswatchSkin || 'noskin'; // TODO remove in v1.12.0+ + + const unreadCounts = results.unreadData.counts; + const unreadCount = { + topic: unreadCounts[''] || 0, + newTopic: unreadCounts.new || 0, + watchedTopic: unreadCounts.watched || 0, + unrepliedTopic: unreadCounts.unreplied || 0, + chat: results.unreadChatCount || 0, + notification: results.unreadNotificationCount || 0, + }; + + Object.keys(unreadCount).forEach(function (key) { + if (unreadCount[key] > 99) { + unreadCount[key] = '99+'; + } + }); + + const tidsByFilter = results.unreadData.tidsByFilter; + results.navigation = results.navigation.map(function (item) { + function modifyNavItem(item, route, filter, content) { + if (item && item.originalRoute === route) { + unreadData[filter] = _.zipObject(tidsByFilter[filter], tidsByFilter[filter].map(() => true)); + item.content = content; + if (unreadCounts[filter] > 0) { + item.iconClass += ' unread-count'; + } } - data.templateValues.scripts = results.scripts.map(function (script) { - return { src: script }; - }); + } + modifyNavItem(item, '/unread', '', unreadCount.topic); + modifyNavItem(item, '/unread?filter=new', 'new', unreadCount.newTopic); + modifyNavItem(item, '/unread?filter=watched', 'watched', unreadCount.watchedTopic); + modifyNavItem(item, '/unread?filter=unreplied', 'unreplied', unreadCount.unrepliedTopic); + return item; + }); - data.templateValues.useCustomJS = meta.config.useCustomJS; - data.templateValues.customJS = data.templateValues.useCustomJS ? meta.config.customJS : ''; - data.templateValues.isSpider = req.uid === -1; - req.app.render('footer', data.templateValues, next); - }, - ], callback); + templateValues.browserTitle = results.browserTitle; + templateValues.navigation = results.navigation; + templateValues.unreadCount = unreadCount; + templateValues.isAdmin = results.user.isAdmin; + templateValues.isGlobalMod = results.user.isGlobalMod; + templateValues.showModMenu = results.user.isAdmin || results.user.isGlobalMod || results.user.isMod; + templateValues.canChat = results.canChat && meta.config.disableChat !== 1; + templateValues.user = results.user; + templateValues.userJSON = jsesc(JSON.stringify(results.user), { isScriptContext: true }); + templateValues.useCustomCSS = meta.config.useCustomCSS && meta.config.customCSS; + templateValues.customCSS = templateValues.useCustomCSS ? (meta.config.renderedCustomCSS || '') : ''; + templateValues.useCustomHTML = meta.config.useCustomHTML; + templateValues.customHTML = templateValues.useCustomHTML ? meta.config.customHTML : ''; + templateValues.maintenanceHeader = meta.config.maintenanceMode && !results.isAdmin; + templateValues.defaultLang = meta.config.defaultLang || 'en-GB'; + templateValues.userLang = res.locals.config.userLang; + templateValues.languageDirection = results.languageDirection; + + templateValues.template = { name: res.locals.template }; + templateValues.template[res.locals.template] = true; + + if (data.hasOwnProperty('_header')) { + templateValues.metaTags = data._header.tags.meta; + templateValues.linkTags = data._header.tags.link; + } + + if (req.route && req.route.path === '/') { + modifyTitle(templateValues); + } + + const hookReturn = await plugins.fireHook('filter:middleware.renderHeader', { + req: req, + res: res, + templateValues: templateValues, + data: data, + }); + + return hookReturn.templateValues; + } + + middleware.renderHeader = async function renderHeader(req, res, data) { + return await req.app.renderAsync('header', await generateHeader(req, res, data)); + }; + + middleware.renderFooter = async function renderFooter(req, res, templateValues) { + const data = await plugins.fireHook('filter:middleware.renderFooter', { + req: req, + res: res, + templateValues: templateValues, + }); + + const results = await utils.promiseParallel({ + scripts: plugins.fireHook('filter:scripts.get', []), + timeagoLocale: (async () => { + const languageCodes = await languages.listCodes(); + const userLang = res.locals.config.userLang; + const timeagoCode = utils.userLangToTimeagoCode(userLang); + + if (languageCodes.includes(userLang) && languages.timeagoCodes.includes(timeagoCode)) { + const pathToLocaleFile = '/vendor/jquery/timeago/locales/jquery.timeago.' + timeagoCode + '.js'; + return nconf.get('relative_path') + '/assets' + pathToLocaleFile; + } + return false; + })(), + }); + + if (results.timeagoLocale) { + results.scripts.push(results.timeagoLocale); + } + data.templateValues.scripts = results.scripts.map(function (script) { + return { src: script }; + }); + + data.templateValues.useCustomJS = meta.config.useCustomJS; + data.templateValues.customJS = data.templateValues.useCustomJS ? meta.config.customJS : ''; + data.templateValues.isSpider = req.uid === -1; + + return await req.app.renderAsync('footer', data.templateValues); }; function modifyTitle(obj) { diff --git a/src/middleware/headers.js b/src/middleware/headers.js index 2bce51b9dc..9d3b20f127 100644 --- a/src/middleware/headers.js +++ b/src/middleware/headers.js @@ -6,9 +6,10 @@ var _ = require('lodash'); var meta = require('../meta'); var languages = require('../languages'); +var helpers = require('./helpers'); module.exports = function (middleware) { - middleware.addHeaders = function addHeaders(req, res, next) { + middleware.addHeaders = helpers.try(function addHeaders(req, res, next) { var headers = { 'X-Powered-By': encodeURI(meta.config['powered-by'] || 'NodeBB'), 'X-Frame-Options': meta.config['allow-from-uri'] ? 'ALLOW-FROM ' + encodeURI(meta.config['allow-from-uri']) : 'SAMEORIGIN', @@ -61,31 +62,30 @@ module.exports = function (middleware) { } next(); - }; + }); - let langs = []; - middleware.autoLocale = function autoLocale(req, res, next) { + middleware.autoLocale = helpers.try(async function autoLocale(req, res, next) { if (parseInt(req.uid, 10) > 0 || !meta.config.autoDetectLang || req.query.lang) { return next(); } - + const langs = await listCodes(); const lang = req.acceptsLanguages(langs); if (!lang) { return next(); } req.query.lang = lang; next(); - }; - - languages.listCodes(function (err, codes) { - if (err) { - winston.error('[middleware/autoLocale] Could not retrieve languages codes list!'); - codes = []; - } - - winston.verbose('[middleware/autoLocale] Retrieves languages list for middleware'); - var defaultLang = meta.config.defaultLang || 'en-GB'; - - langs = _.uniq([defaultLang, ...codes]); }); + + async function listCodes() { + const defaultLang = meta.config.defaultLang || 'en-GB'; + try { + const codes = await languages.listCodes(); + winston.verbose('[middleware/autoLocale] Retrieves languages list for middleware'); + return _.uniq([defaultLang, ...codes]); + } catch (err) { + winston.error('[middleware/autoLocale] Could not retrieve languages codes list! ' + err.stack); + return [defaultLang]; + } + } }; diff --git a/src/middleware/helpers.js b/src/middleware/helpers.js new file mode 100644 index 0000000000..cb67b454c5 --- /dev/null +++ b/src/middleware/helpers.js @@ -0,0 +1,22 @@ +'use strict'; + +const helpers = module.exports; + +helpers.try = function (middleware) { + if (middleware && middleware.constructor && middleware.constructor.name === 'AsyncFunction') { + return async function (req, res, next) { + try { + await middleware(req, res, next); + } catch (err) { + next(err); + } + }; + } + return function (req, res, next) { + try { + middleware(req, res, next); + } catch (err) { + next(err); + } + }; +}; diff --git a/src/middleware/index.js b/src/middleware/index.js index 9af5605885..b84cfd35af 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -8,6 +8,7 @@ var nconf = require('nconf'); var ensureLoggedIn = require('connect-ensure-login'); var toobusy = require('toobusy-js'); var LRU = require('lru-cache'); +var util = require('util'); var plugins = require('../plugins'); var meta = require('../meta'); @@ -15,6 +16,7 @@ var user = require('../user'); var groups = require('../groups'); var analytics = require('../analytics'); var privileges = require('../privileges'); +var helpers = require('./helpers'); var controllers = { api: require('../controllers/api'), @@ -31,7 +33,7 @@ middleware.regexes = { timestampedUpload: /^\d+-.+$/, }; -middleware.applyCSRF = csrf({ +const csurfMiddleware = csrf({ cookie: nconf.get('url_parsed').protocol === 'https:' ? { secure: true, sameSite: 'Strict', @@ -39,6 +41,14 @@ middleware.applyCSRF = csrf({ } : true, }); +middleware.applyCSRF = function (req, res, next) { + if (req.uid >= 0) { + csurfMiddleware(req, res, next); + } else { + next(); + } +}; + middleware.ensureLoggedIn = ensureLoggedIn.ensureLoggedIn(nconf.get('relative_path') + '/login'); require('./admin')(middleware); @@ -51,56 +61,39 @@ require('./headers')(middleware); middleware.stripLeadingSlashes = function stripLeadingSlashes(req, res, next) { var target = req.originalUrl.replace(nconf.get('relative_path'), ''); if (target.startsWith('//')) { - res.redirect(nconf.get('relative_path') + target.replace(/^\/+/, '/')); - } else { - setImmediate(next); + return res.redirect(nconf.get('relative_path') + target.replace(/^\/+/, '/')); } + next(); }; -middleware.pageView = function pageView(req, res, next) { - analytics.pageView({ - ip: req.ip, - uid: req.uid, +middleware.pageView = helpers.try(async function pageView(req, res, next) { + const promises = [ + analytics.pageView({ ip: req.ip, uid: req.uid }), + ]; + if (req.loggedIn) { + promises.push(user.updateOnlineUsers(req.uid)); + promises.push(user.updateLastOnlineTime(req.uid)); + } + await Promise.all(promises); + plugins.fireHook('action:middleware.pageView', { req: req }); + next(); +}); + +middleware.pluginHooks = helpers.try(async function pluginHooks(req, res, next) { + // TODO: Deprecate in v2.0 + await async.each(plugins.loadedHooks['filter:router.page'] || [], function (hookObj, next) { + hookObj.method(req, res, next); }); - plugins.fireHook('action:middleware.pageView', { req: req }); - - if (req.loggedIn) { - if (req.path.startsWith('/api/users') || req.path.startsWith('/users')) { - async.parallel([ - async.apply(user.updateOnlineUsers, req.uid), - async.apply(user.updateLastOnlineTime, req.uid), - ], next); - } else { - user.updateOnlineUsers(req.uid); - user.updateLastOnlineTime(req.uid); - setImmediate(next); - } - } else { - setImmediate(next); - } -}; - - -middleware.pluginHooks = async function pluginHooks(req, res, next) { - // TODO: Deprecate in v2.0 - try { - await async.each(plugins.loadedHooks['filter:router.page'] || [], function (hookObj, next) { - hookObj.method(req, res, next); - }); - - await plugins.fireHook('response:router.page', { - req: req, - res: res, - }); - } catch (err) { - return next(err); - } + await plugins.fireHook('response:router.page', { + req: req, + res: res, + }); if (!res.headersSent) { next(); } -}; +}); middleware.validateFiles = function validateFiles(req, res, next) { if (!Array.isArray(req.files.files) || !req.files.files.length) { @@ -131,36 +124,28 @@ middleware.routeTouchIcon = function routeTouchIcon(req, res) { }); }; -middleware.privateTagListing = function privateTagListing(req, res, next) { - privileges.global.can('view:tags', req.uid, function (err, canView) { - if (err || canView) { - return next(err); - } - controllers.helpers.notAllowed(req, res); - }); -}; +middleware.privateTagListing = helpers.try(async function privateTagListing(req, res, next) { + const canView = await privileges.global.can('view:tags', req.uid); + if (!canView) { + return controllers.helpers.notAllowed(req, res); + } + next(); +}); -middleware.exposeGroupName = function exposeGroupName(req, res, next) { - expose('groupName', groups.getGroupNameByGroupSlug, 'slug', req, res, next); -}; +middleware.exposeGroupName = helpers.try(async function exposeGroupName(req, res, next) { + await expose('groupName', groups.getGroupNameByGroupSlug, 'slug', req, res, next); +}); -middleware.exposeUid = function exposeUid(req, res, next) { - expose('uid', user.getUidByUserslug, 'userslug', req, res, next); -}; +middleware.exposeUid = helpers.try(async function exposeUid(req, res, next) { + await expose('uid', user.getUidByUserslug, 'userslug', req, res, next); +}); -function expose(exposedField, method, field, req, res, next) { +async function expose(exposedField, method, field, req, res, next) { if (!req.params.hasOwnProperty(field)) { return next(); } - async.waterfall([ - function (next) { - method(req.params[field], next); - }, - function (id, next) { - res.locals[exposedField] = id; - next(); - }, - ], next); + res.locals[exposedField] = await method(req.params[field]); + next(); } middleware.privateUploads = function privateUploads(req, res, next) { @@ -188,10 +173,13 @@ middleware.busyCheck = function busyCheck(req, res, next) { } }; -middleware.applyBlacklist = function applyBlacklist(req, res, next) { - meta.blacklist.test(req.ip, function (err) { +middleware.applyBlacklist = async function applyBlacklist(req, res, next) { + try { + await meta.blacklist.test(req.ip); + next(); + } catch (err) { next(err); - }); + } }; middleware.delayLoading = function delayLoading(req, res, next) { @@ -207,25 +195,19 @@ middleware.delayLoading = function delayLoading(req, res, next) { setTimeout(next, 1000); }; -middleware.buildSkinAsset = function buildSkinAsset(req, res, next) { +middleware.buildSkinAsset = helpers.try(async function buildSkinAsset(req, res, next) { // If this middleware is reached, a skin was requested, so it is built on-demand - var target = path.basename(req.originalUrl).match(/(client-[a-z]+)/); - if (target) { - async.waterfall([ - async.apply(plugins.prepareForBuild, ['client side styles']), - async.apply(meta.css.buildBundle, target[0], true), - ], function (err, css) { - if (err) { - return next(); - } - - require('../meta/minifier').killAll(); - res.status(200).type('text/css').send(css); - }); - } else { - setImmediate(next); + const target = path.basename(req.originalUrl).match(/(client-[a-z]+)/); + if (!target) { + return next(); } -}; + + await plugins.prepareForBuild(['client side styles']); + const buildBundle = util.promisify(meta.css.buildBundle); + const css = await buildBundle(target[0], true); + require('../meta/minifier').killAll(); + res.status(200).type('text/css').send(css); +}); middleware.trimUploadTimestamps = function trimUploadTimestamps(req, res, next) { // Check match @@ -238,19 +220,18 @@ middleware.trimUploadTimestamps = function trimUploadTimestamps(req, res, next) next(); }; -middleware.validateAuth = function validateAuth(req, res, next) { - plugins.fireHook('static:auth.validate', { - user: res.locals.user, - strategy: res.locals.strategy, - }, function (err) { - if (err) { - return req.session.regenerate(function () { - req.uid = 0; - req.loggedIn = false; - next(err); - }); - } - +middleware.validateAuth = helpers.try(async function validateAuth(req, res, next) { + try { + await plugins.fireHook('static:auth.validate', { + user: res.locals.user, + strategy: res.locals.strategy, + }); next(); - }); -}; + } catch (err) { + const regenerateSession = util.promisify(cb => req.session.regenerate(cb)); + await regenerateSession(); + req.uid = 0; + req.loggedIn = false; + next(err); + } +}); diff --git a/src/middleware/maintenance.js b/src/middleware/maintenance.js index 35f28f4b57..2c7f4b9f0c 100644 --- a/src/middleware/maintenance.js +++ b/src/middleware/maintenance.js @@ -4,11 +4,12 @@ const util = require('util'); const nconf = require('nconf'); const meta = require('../meta'); const user = require('../user'); +const helpers = require('./helpers'); module.exports = function (middleware) { - middleware.maintenanceMode = async function maintenanceMode(req, res, next) { + middleware.maintenanceMode = helpers.try(async function maintenanceMode(req, res, next) { if (!meta.config.maintenanceMode) { - return setImmediate(next); + return next(); } const hooksAsync = util.promisify(middleware.pluginHooks); @@ -16,12 +17,12 @@ module.exports = function (middleware) { const url = req.url.replace(nconf.get('relative_path'), ''); if (url.startsWith('/login') || url.startsWith('/api/login')) { - return setImmediate(next); + return next(); } const isAdmin = await user.isAdministrator(req.uid); if (isAdmin) { - return setImmediate(next); + return next(); } res.status(meta.config.maintenanceModeStatus); @@ -34,8 +35,7 @@ module.exports = function (middleware) { if (res.locals.isAPI) { return res.json(data); } - const buildHeaderAsync = util.promisify(middleware.buildHeader); - await buildHeaderAsync(req, res); + await middleware.buildHeaderAsync(req, res); res.render('503', data); - }; + }); }; diff --git a/src/middleware/render.js b/src/middleware/render.js index a6257d04a8..1e9d20b0b0 100644 --- a/src/middleware/render.js +++ b/src/middleware/render.js @@ -12,8 +12,6 @@ const widgets = require('../widgets'); const utils = require('../utils'); module.exports = function (middleware) { - const renderHeaderFooterAsync = util.promisify(renderHeaderFooter); - middleware.processRender = function processRender(req, res, next) { // res.render post-processing, modified from here: https://gist.github.com/mrlannigan/5051687 const render = res.render; @@ -63,9 +61,9 @@ module.exports = function (middleware) { const renderAsync = util.promisify((templateToRender, options, next) => render.call(self, templateToRender, options, next)); const results = await utils.promiseParallel({ - header: renderHeaderFooterAsync('renderHeader', req, res, options), + header: renderHeaderFooter('renderHeader', req, res, options), content: renderAsync(templateToRender, options), - footer: renderHeaderFooterAsync('renderFooter', req, res, options), + footer: renderHeaderFooter('renderFooter', req, res, options), }); const str = results.header + @@ -89,14 +87,13 @@ module.exports = function (middleware) { next(); }; - function renderHeaderFooter(method, req, res, options, next) { + async function renderHeaderFooter(method, req, res, options) { if (res.locals.renderHeader) { - middleware[method](req, res, options, next); + return await middleware[method](req, res, options); } else if (res.locals.renderAdminHeader) { - middleware.admin[method](req, res, options, next); - } else { - next(null, ''); + return await middleware.admin[method](req, res, options); } + return ''; } async function translate(str, req, res) { diff --git a/src/middleware/user.js b/src/middleware/user.js index e2d88f84d7..e814458e8c 100644 --- a/src/middleware/user.js +++ b/src/middleware/user.js @@ -1,6 +1,5 @@ 'use strict'; -const util = require('util'); const nconf = require('nconf'); const winston = require('winston'); @@ -8,7 +7,7 @@ const meta = require('../meta'); const user = require('../user'); const privileges = require('../privileges'); const plugins = require('../plugins'); - +const helpers = require('./helpers'); const auth = require('../routes/authentication'); const controllers = { @@ -16,9 +15,9 @@ const controllers = { }; module.exports = function (middleware) { - async function authenticate(req, res, next, callback) { + async function authenticate(req, res) { if (req.loggedIn) { - return next(); + return true; } await plugins.fireHook('response:middleware.authenticate', { @@ -28,35 +27,35 @@ module.exports = function (middleware) { }); if (!res.headersSent) { - auth.setAuthVars(req, res, function () { - if (req.loggedIn && req.user && req.user.uid) { - return next(); - } - - callback(); - }); + auth.setAuthVars(req); } + return !res.headersSent; } - middleware.authenticate = function middlewareAuthenticate(req, res, next) { - authenticate(req, res, next, function () { - controllers.helpers.notAllowed(req, res, next); - }); - }; + middleware.authenticate = helpers.try(async function middlewareAuthenticate(req, res, next) { + if (!await authenticate(req, res)) { + return; + } + if (!req.loggedIn) { + return controllers.helpers.notAllowed(req, res); + } + next(); + }); - const authenticateAsync = util.promisify(middleware.authenticate); + middleware.authenticateOrGuest = helpers.try(async function authenticateOrGuest(req, res, next) { + if (!await authenticate(req, res)) { + return; + } + next(); + }); - middleware.authenticateOrGuest = function authenticateOrGuest(req, res, next) { - authenticate(req, res, next, next); - }; + middleware.ensureSelfOrGlobalPrivilege = helpers.try(async function ensureSelfOrGlobalPrivilege(req, res, next) { + await ensureSelfOrMethod(user.isAdminOrGlobalMod, req, res, next); + }); - middleware.ensureSelfOrGlobalPrivilege = function ensureSelfOrGlobalPrivilege(req, res, next) { - ensureSelfOrMethod(user.isAdminOrGlobalMod, req, res, next); - }; - - middleware.ensureSelfOrPrivileged = function ensureSelfOrPrivileged(req, res, next) { - ensureSelfOrMethod(user.isPrivileged, req, res, next); - }; + middleware.ensureSelfOrPrivileged = helpers.try(async function ensureSelfOrPrivileged(req, res, next) { + await ensureSelfOrMethod(user.isPrivileged, req, res, next); + }); async function ensureSelfOrMethod(method, req, res, next) { /* @@ -67,7 +66,7 @@ module.exports = function (middleware) { return controllers.helpers.notAllowed(req, res); } if (req.uid === parseInt(res.locals.uid, 10)) { - return setImmediate(next); + return next(); } const allowed = await method(req.uid); if (!allowed) { @@ -77,12 +76,12 @@ module.exports = function (middleware) { return next(); } - middleware.checkGlobalPrivacySettings = function checkGlobalPrivacySettings(req, res, next) { + middleware.checkGlobalPrivacySettings = helpers.try(async function checkGlobalPrivacySettings(req, res, next) { winston.warn('[middleware], checkGlobalPrivacySettings deprecated, use canViewUsers or canViewGroups'); - middleware.canViewUsers(req, res, next); - }; + await middleware.canViewUsers(req, res, next); + }); - middleware.canViewUsers = async function canViewUsers(req, res, next) { + middleware.canViewUsers = helpers.try(async function canViewUsers(req, res, next) { if (parseInt(res.locals.uid, 10) === req.uid) { return next(); } @@ -91,19 +90,24 @@ module.exports = function (middleware) { return next(); } controllers.helpers.notAllowed(req, res); - }; + }); - middleware.canViewGroups = async function canViewGroups(req, res, next) { + middleware.canViewGroups = helpers.try(async function canViewGroups(req, res, next) { const canView = await privileges.global.can('view:groups', req.uid); if (canView) { return next(); } controllers.helpers.notAllowed(req, res); - }; + }); - middleware.checkAccountPermissions = async function checkAccountPermissions(req, res, next) { + middleware.checkAccountPermissions = helpers.try(async function checkAccountPermissions(req, res, next) { // This middleware ensures that only the requested user and admins can pass - await authenticateAsync(req, res); + if (!await authenticate(req, res)) { + return; + } + if (!req.loggedIn) { + return controllers.helpers.notAllowed(req, res); + } const uid = await user.getUidByUserslug(req.params.userslug); let allowed = await privileges.users.canEdit(req.uid, uid); if (allowed) { @@ -117,17 +121,17 @@ module.exports = function (middleware) { return next(); } controllers.helpers.notAllowed(req, res); - }; + }); - middleware.redirectToAccountIfLoggedIn = async function redirectToAccountIfLoggedIn(req, res, next) { + middleware.redirectToAccountIfLoggedIn = helpers.try(async function redirectToAccountIfLoggedIn(req, res, next) { if (req.session.forceLogin || req.uid <= 0) { return next(); } const userslug = await user.getUserField(req.uid, 'userslug'); controllers.helpers.redirect(res, '/user/' + userslug); - }; + }); - middleware.redirectUidToUserslug = async function redirectUidToUserslug(req, res, next) { + middleware.redirectUidToUserslug = helpers.try(async function redirectUidToUserslug(req, res, next) { const uid = parseInt(req.params.uid, 10); if (uid <= 0) { return next(); @@ -140,18 +144,18 @@ module.exports = function (middleware) { .replace('uid', 'user') .replace(uid, function () { return userslug; }); controllers.helpers.redirect(res, path); - }; + }); - middleware.redirectMeToUserslug = async function redirectMeToUserslug(req, res) { + middleware.redirectMeToUserslug = helpers.try(async function redirectMeToUserslug(req, res) { const userslug = await user.getUserField(req.uid, 'userslug'); if (!userslug) { return controllers.helpers.notAllowed(req, res); } const path = req.path.replace(/^(\/api)?\/me/, '/user/' + userslug); controllers.helpers.redirect(res, path); - }; + }); - middleware.isAdmin = async function isAdmin(req, res, next) { + middleware.isAdmin = helpers.try(async function isAdmin(req, res, next) { const isAdmin = await user.isAdministrator(req.uid); if (!isAdmin) { return controllers.helpers.notAllowed(req, res); @@ -186,7 +190,7 @@ module.exports = function (middleware) { } else { res.redirect(nconf.get('relative_path') + '/login?local=1'); } - }; + }); middleware.requireUser = function (req, res, next) { if (req.loggedIn) { diff --git a/src/routes/api.js b/src/routes/api.js index 7d71051e92..1e94de1d96 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -8,13 +8,7 @@ module.exports = function (app, middleware, controllers) { var router = express.Router(); app.use('/api', router); - router.get('/config', function (req, res, next) { - if (req.uid >= 0) { - middleware.applyCSRF(req, res, next); - } else { - setImmediate(next); - } - }, controllers.api.getConfig); + router.get('/config', middleware.applyCSRF, controllers.api.getConfig); router.get('/me', controllers.user.getCurrentUser); router.get('/user/uid/:uid', middleware.canViewUsers, controllers.user.getUserByUID); diff --git a/src/routes/authentication.js b/src/routes/authentication.js index 555c75d778..1f26c23980 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -23,14 +23,17 @@ Auth.initialize = function (app, middleware) { passportSessionMiddleware(req, res, next); }); - app.use(Auth.setAuthVars); + app.use(function (req, res, next) { + Auth.setAuthVars(req, res); + next(); + }); Auth.app = app; Auth.middleware = middleware; }; -Auth.setAuthVars = function setAuthVars(req, res, next) { - var isSpider = req.isSpider(); +Auth.setAuthVars = function setAuthVars(req) { + const isSpider = req.isSpider(); req.loggedIn = !isSpider && !!req.user; if (req.user) { req.uid = parseInt(req.user.uid, 10); @@ -39,7 +42,6 @@ Auth.setAuthVars = function setAuthVars(req, res, next) { } else { req.uid = 0; } - next(); }; Auth.getLoginStrategies = function () { diff --git a/src/routes/helpers.js b/src/routes/helpers.js index 85c3dd1196..8c2085d42d 100644 --- a/src/routes/helpers.js +++ b/src/routes/helpers.js @@ -5,7 +5,7 @@ var helpers = module.exports; helpers.setupPageRoute = function (router, name, middleware, middlewares, controller) { middlewares = [middleware.maintenanceMode, middleware.registrationComplete, middleware.pageView, middleware.pluginHooks].concat(middlewares); - router.get(name, middleware.busyCheck, middleware.buildHeader, middlewares, helpers.tryRoute(controller)); + router.get(name, middleware.busyCheck, middleware.applyCSRF, middleware.buildHeader, middlewares, helpers.tryRoute(controller)); router.get('/api' + name, middlewares, helpers.tryRoute(controller)); }; diff --git a/src/routes/index.js b/src/routes/index.js index fcab003624..2274a7f418 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -56,7 +56,7 @@ function topicRoutes(app, middleware, controllers) { function postRoutes(app, middleware, controllers) { const middlewares = [middleware.maintenanceMode, middleware.registrationComplete, middleware.pluginHooks]; - app.get('/post/:pid', middleware.busyCheck, middleware.buildHeader, middlewares, controllers.posts.redirectToPost); + app.get('/post/:pid', middleware.busyCheck, middlewares, controllers.posts.redirectToPost); app.get('/api/post/:pid', middlewares, controllers.posts.redirectToPost); }