mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-06-26 06:51:41 +02:00
Merge commit '01aeb45af89cd5d64f9944e545c9684ed8e1ac18' into weekly
This commit is contained in:
8
app.js
8
app.js
@@ -118,7 +118,7 @@ function start() {
|
||||
var urlObject = url.parse(nconf.get('url'));
|
||||
var relativePath = urlObject.pathname !== '/' ? urlObject.pathname : '';
|
||||
nconf.set('base_url', urlObject.protocol + '//' + urlObject.host);
|
||||
nconf.set('secure', urlObject.protocol === 'https');
|
||||
nconf.set('secure', urlObject.protocol === 'https:');
|
||||
nconf.set('use_port', !!urlObject.port);
|
||||
nconf.set('relative_path', relativePath);
|
||||
nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || 4567);
|
||||
@@ -181,7 +181,11 @@ function start() {
|
||||
require('./src/meta').configs.init(next);
|
||||
},
|
||||
function(next) {
|
||||
require('./src/meta').dependencies.check(next);
|
||||
if (nconf.get('dep-check') === undefined || nconf.get('dep-check') !== false) {
|
||||
require('./src/meta').dependencies.check(next);
|
||||
} else {
|
||||
setImmediate(next);
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
require('./src/upgrade').check(next);
|
||||
|
||||
@@ -51,9 +51,9 @@
|
||||
"nodebb-plugin-composer-default": "4.0.2",
|
||||
"nodebb-plugin-dbsearch": "1.0.1",
|
||||
"nodebb-plugin-emoji-extended": "1.1.0",
|
||||
"nodebb-plugin-emoji-one": "1.1.3",
|
||||
"nodebb-plugin-emoji-one": "1.1.4",
|
||||
"nodebb-plugin-markdown": "5.1.5",
|
||||
"nodebb-plugin-mentions": "1.1.1",
|
||||
"nodebb-plugin-mentions": "1.1.2",
|
||||
"nodebb-plugin-soundpack-default": "0.1.6",
|
||||
"nodebb-plugin-spam-be-gone": "0.4.6",
|
||||
"nodebb-rewards-essentials": "0.0.8",
|
||||
@@ -118,4 +118,4 @@
|
||||
"url": "https://github.com/barisusakli"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<head>
|
||||
<title>Excessive Load Warning</title>
|
||||
<link href='http://fonts.googleapis.com/css?family=Ubuntu:400,500,700' rel='stylesheet' type='text/css'>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: #00A9EA;
|
||||
@@ -32,6 +33,20 @@
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
h1 {
|
||||
font-size: 125px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
p strong {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
@@ -148,11 +163,13 @@
|
||||
<div class="center">
|
||||
<h1 id="click-me" class="animated bounce">503</h1>
|
||||
<p>
|
||||
<strong>This forum is temporarily unavailable due to excessive load.</strong> <br />
|
||||
<strong>This forum is temporarily unavailable due to excessive load.</strong>
|
||||
</p>
|
||||
<p>
|
||||
We shouldn't be down for long. Please check back shortly. Sorry for the inconvenience!
|
||||
</p>
|
||||
<p id="hide" class="hide">
|
||||
<small>Alright. You can stop clicking... it's not going to make the site come back sooner!</small>
|
||||
<p>
|
||||
<small id="hide" class="hide">Alright. You can stop clicking... it's not going to make the site come back sooner!</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"invalid-password": "Ungültiges Passwort",
|
||||
"invalid-username-or-password": "Bitte gebe einen Benutzernamen und ein Passwort an",
|
||||
"invalid-search-term": "Ungültige Suchanfrage",
|
||||
"csrf-invalid": "We were unable to log you in, likely due to an expired session. Please try again",
|
||||
"csrf-invalid": "Dein Login war nicht erfolgreich da wahrscheinlich deine Sitzung abgelaufen ist. Bitte versuche es noch einmal",
|
||||
"invalid-pagination-value": "Ungültige Seitennummerierung, muss mindestens %1 und maximal %2 sein",
|
||||
"username-taken": "Der Benutzername ist bereits vergeben",
|
||||
"email-taken": "Die E-Mail-Adresse ist bereits vergeben",
|
||||
@@ -23,7 +23,7 @@
|
||||
"no-email-to-confirm": "Dieses Forum setzt eine E-Mail-Bestätigung voraus, bitte klicke hier um eine E-Mail-Adresse einzugeben.",
|
||||
"email-confirm-failed": "Wir konnten deine E-Mail-Adresse nicht bestätigen, bitte versuch es später noch einmal",
|
||||
"confirm-email-already-sent": "Die Bestätigungsmail wurde verschickt, bitte warte %1 Minute(n) um eine Weitere zu verschicken.",
|
||||
"sendmail-not-found": "The sendmail executable could not be found, please ensure it is installed and executable by the user running NodeBB.",
|
||||
"sendmail-not-found": "Sendmail wurde nicht gefunden. Bitte stelle sicher, dass es installiert ist und durch den Benutzer unter dem NodeBB läuft ausgeführt werden kann.",
|
||||
"username-too-short": "Benutzername ist zu kurz",
|
||||
"username-too-long": "Benutzername ist zu lang",
|
||||
"password-too-long": "Passwort ist zu lang",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"remember_me": "Eingeloggt bleiben?",
|
||||
"forgot_password": "Passwort vergessen?",
|
||||
"alternative_logins": "Alternative Logins",
|
||||
"failed_login_attempt": "Login Unsuccessful",
|
||||
"failed_login_attempt": "Login fehlgeschlagen",
|
||||
"login_successful": "Du hast dich erfolgreich eingeloggt!",
|
||||
"dont_have_account": "Du hast noch kein Konto?"
|
||||
}
|
||||
@@ -29,14 +29,14 @@
|
||||
"composer.submit_and_lock": "Einreichen und Sperren",
|
||||
"composer.toggle_dropdown": "Menu aus-/einblenden",
|
||||
"composer.uploading": "Lade %1 hoch",
|
||||
"composer.formatting.bold": "Bold",
|
||||
"composer.formatting.italic": "Italic",
|
||||
"composer.formatting.list": "List",
|
||||
"composer.formatting.strikethrough": "Strikethrough",
|
||||
"composer.formatting.bold": "Fett",
|
||||
"composer.formatting.italic": "Kursiv",
|
||||
"composer.formatting.list": "Liste",
|
||||
"composer.formatting.strikethrough": "Durchstreichen",
|
||||
"composer.formatting.link": "Link",
|
||||
"composer.formatting.picture": "Picture",
|
||||
"composer.upload-picture": "Upload Image",
|
||||
"composer.upload-file": "Upload File",
|
||||
"composer.formatting.picture": "Bild",
|
||||
"composer.upload-picture": "Bild hochladen",
|
||||
"composer.upload-file": "Datei hochladen",
|
||||
"bootbox.ok": "OK",
|
||||
"bootbox.cancel": "Abbrechen",
|
||||
"bootbox.confirm": "Bestätigen",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"deleted_message": "Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.",
|
||||
"following_topic.message": "Du erhälst nun eine Benachrichtigung, wenn jemand einen Beitrag zu diesem Thema verfasst.",
|
||||
"not_following_topic.message": "Du erhälst keine weiteren Benachrichtigungen zu diesem Thema mehr.",
|
||||
"ignoring_topic.message": "You will no longer see this topic in the unread topics list. You will be notified when you are mentioned or your post is up voted.",
|
||||
"ignoring_topic.message": "Ungelesene Beiträge in diesem Thema werden nicht mehr angezeigt. Du erhältst eine Benachrichtigung wenn du in diesem Thema erwähnt wirst oder deine Beiträge positiv bewertet werden.",
|
||||
"login_to_subscribe": "Bitte registrieren oder einloggen um dieses Thema zu abonnieren",
|
||||
"markAsUnreadForAll.success": "Thema für Alle als ungelesen markiert.",
|
||||
"mark_unread": "Als ungelesen markieren",
|
||||
@@ -42,12 +42,12 @@
|
||||
"watch.title": "Bei neuen Antworten benachrichtigen",
|
||||
"unwatch.title": "Dieses Thema nicht mehr beobachten",
|
||||
"share_this_post": "Diesen Beitrag teilen",
|
||||
"watching": "Watching",
|
||||
"not-watching": "Not Watching",
|
||||
"ignoring": "Ignoring",
|
||||
"watching.description": "Notify me of new replies.<br/>Show topic in unread.",
|
||||
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
|
||||
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
|
||||
"watching": "Beobachtet",
|
||||
"not-watching": "Nicht beobachtet",
|
||||
"ignoring": "Ignoriert",
|
||||
"watching.description": "Benachrichtigung bei neuen Beiträgen.<br/>Ungelesen Beiträge anzeigen.",
|
||||
"not-watching.description": "Keine Benachrichtigung bei neuen Beiträgen.<br/>Ungelesen Beiträge anzeigen wenn die Kategorie nicht ignoriert wird.",
|
||||
"ignoring.description": "Keine Benachrichtigung bei neuen Beiträgen.<br/>Ungelesene Beiträge nicht anzeigen.",
|
||||
"thread_tools.title": "Themen-Werkzeuge",
|
||||
"thread_tools.markAsUnreadForAll": "Als ungelesen markieren",
|
||||
"thread_tools.pin": "Thema anheften",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"all": "Alle",
|
||||
"all_categories": "Alle Kategorien",
|
||||
"topics_marked_as_read.success": "Themen als gelesen markiert!",
|
||||
"all-topics": "All Topics",
|
||||
"new-topics": "New Topics",
|
||||
"watched-topics": "Watched Topics"
|
||||
"all-topics": "Alle Themen",
|
||||
"new-topics": "Neue Themen",
|
||||
"watched-topics": "Beobachtete Themen"
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
"digest.day": "jour",
|
||||
"digest.week": "semaine",
|
||||
"digest.month": "mois",
|
||||
"digest.subject": "Compte-rendu pour %1",
|
||||
"digest.subject": "Résumé de l'actualité de %1",
|
||||
"notif.chat.subject": "Nouveau message de chat reçu de %1",
|
||||
"notif.chat.cta": "Cliquez ici pour continuer la conversation",
|
||||
"notif.chat.unsub.info": "Cette notification de chat a été envoyé en raison de vos paramètres d'abonnement.",
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"signature-too-long": "La signature ne peut dépasser %1 caractère(s).",
|
||||
"about-me-too-long": "Votre texte \"à propos de moi\" ne peut dépasser %1 caractère(s).",
|
||||
"cant-chat-with-yourself": "Vous ne pouvez chatter avec vous même !",
|
||||
"chat-restricted": "Cet utilisateur a restreint les ses messages de chat. Il doit d'abord vous suivre avant de pouvoir discuter avec lui.",
|
||||
"chat-restricted": "Cet utilisateur a restreint les ses messages de chat. Il doit d'abord s'abonner à votre compte avant que vous puissiez discuter avec lui.",
|
||||
"chat-disabled": "Système de chat désactivé",
|
||||
"too-many-messages": "Vous avez envoyé trop de messages, veuillez patienter un instant.",
|
||||
"invalid-chat-message": "Message de Chat invalide",
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
"user_posted_to_multiple": "<strong>%1</strong> et %2 autres ont posté une réponse à : <strong>%3</strong>",
|
||||
"user_posted_topic": "<strong>%1</strong> a posté un nouveau sujet: <strong>%2</strong>.",
|
||||
"user_started_following_you": "<strong>%1</strong> vous suit.",
|
||||
"user_started_following_you_dual": "<strong>%1</strong> et <strong>%2</strong> vous suivent.",
|
||||
"user_started_following_you_multiple": "<strong>%1</strong> et %2 autres vous suivent.",
|
||||
"user_started_following_you_dual": "<strong>%1</strong> et <strong>%2</strong> se sont abonnés à votre compte.",
|
||||
"user_started_following_you_multiple": "<strong>%1</strong> et %2 autres se sont abonnés à votre compte.",
|
||||
"new_register": "<strong>%1</strong> a envoyé une demande d'incription.",
|
||||
"new_register_multiple": "<strong>%1</strong> inscription(s) est en attente de validation.",
|
||||
"email-confirmed": "Email vérifié",
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
"group": "%1 groupe",
|
||||
"chats": "Discussions",
|
||||
"chat": "Conversation avec %1",
|
||||
"account/edit": "Edition de \"%1\"",
|
||||
"account/edit": "Édition de \"%1\"",
|
||||
"account/edit/password": "Édition du mot de passe de \"%1\"",
|
||||
"account/edit/username": "Édition du nom d'utilisateur de \"%1\"",
|
||||
"account/edit/email": "Édition de l'e-mail de \"%1\"",
|
||||
"account/following": "Les personnes auxquelles %1 est abonné",
|
||||
"account/followers": "Les personnes qui suivent %1",
|
||||
"account/followers": "Les personnes abonnées à %1",
|
||||
"account/posts": "Messages postés par %1",
|
||||
"account/topics": "Sujets créés par %1",
|
||||
"account/groups": "Groupes auxquels appartient %1",
|
||||
@@ -41,6 +41,6 @@
|
||||
"account/best": "Meilleurs messages postés par %1",
|
||||
"confirm": "Email vérifié",
|
||||
"maintenance.text": "%1 est en maintenance. Veuillez revenir un peu plus tard.",
|
||||
"maintenance.messageIntro": "De plus, l'administrateur a laissé ce message:",
|
||||
"maintenance.messageIntro": "De plus, l'administrateur a laissé ce message :",
|
||||
"throttled.text": "%1 est actuellement indisponible en raison d'une charge excessive. Merci de réessayer plus tard."
|
||||
}
|
||||
@@ -64,8 +64,8 @@
|
||||
"settings": "Paramètres",
|
||||
"show_email": "Afficher mon email",
|
||||
"show_fullname": "Afficher mon nom complet",
|
||||
"restrict_chats": "Autoriser la réception de messages ne provenant que des personnes que je suis",
|
||||
"digest_label": "S’inscrire aux comptes-rendus",
|
||||
"restrict_chats": "Autoriser la réception de messages ne provenant que des personnes auxquelles je suis abonné",
|
||||
"digest_label": "S’inscrire aux résumés de l'actualité du forum",
|
||||
"digest_description": "S'abonner par email aux mises à jours de ce forum (nouvelles notifications et nouveaux sujets) selon le planning sélectionné.",
|
||||
"digest_off": "Désactivé",
|
||||
"digest_daily": "Quotidien",
|
||||
@@ -74,8 +74,8 @@
|
||||
"send_chat_notifications": "Envoyer un e-mail si un nouveau message de chat arrive lorsque je ne suis pas en ligne",
|
||||
"send_post_notifications": "Envoyer un email lors de réponses envoyées aux sujets auxquels je suis abonné",
|
||||
"settings-require-reload": "Certains réglages nécessitent un rechargement. Cliquez ici pour recharger la page.",
|
||||
"has_no_follower": "Cet utilisateur n'est suivi par personne :(",
|
||||
"follows_no_one": "Cet utilisateur ne suit personne :(",
|
||||
"has_no_follower": "Personne n'est abonné à cet utilisateur :(",
|
||||
"follows_no_one": "Cet utilisateur n'est abonné à personne :(",
|
||||
"has_no_posts": "Cet utilisateur n'a encore rien posté.",
|
||||
"has_no_topics": "Cet utilisateur n'a encore créé aucun sujet.",
|
||||
"has_no_watched_topics": "Cet utilisateur ne s'est encore abonné à aucun sujet.",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"invalid-password": "Ongeldig wachtwoord",
|
||||
"invalid-username-or-password": "Geef zowel een gebruikersnaam als wachtwoord op",
|
||||
"invalid-search-term": "Ongeldig zoekterm",
|
||||
"csrf-invalid": "We were unable to log you in, likely due to an expired session. Please try again",
|
||||
"csrf-invalid": "We konden u niet aanmelden, waarschijnlijk door een verlopen sessie. Probeer het a.u.b. nogmaals.",
|
||||
"invalid-pagination-value": "Invalide paginering waarde. De waarde moet op z'n minst %1 zijn en niet hoger dan %2 zijn.",
|
||||
"username-taken": "Gebruikersnaam is al in gebruik ",
|
||||
"email-taken": "E-mailadres is al in gebruik",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"remember_me": "Aangemeld blijven?",
|
||||
"forgot_password": "Wachtwoord vergeten?",
|
||||
"alternative_logins": "Andere manieren van aanmelden",
|
||||
"failed_login_attempt": "Login Unsuccessful",
|
||||
"failed_login_attempt": "Aanmelden mislukt",
|
||||
"login_successful": "Je bent succesvol ingelogd!",
|
||||
"dont_have_account": "Geen gebruikersaccount?"
|
||||
}
|
||||
@@ -29,14 +29,14 @@
|
||||
"composer.submit_and_lock": "Bericht plaatsen en sluiten",
|
||||
"composer.toggle_dropdown": "Keuzelijst schakelen",
|
||||
"composer.uploading": "Uploaden van %1",
|
||||
"composer.formatting.bold": "Bold",
|
||||
"composer.formatting.italic": "Italic",
|
||||
"composer.formatting.list": "List",
|
||||
"composer.formatting.strikethrough": "Strikethrough",
|
||||
"composer.formatting.bold": "Vet",
|
||||
"composer.formatting.italic": "Cursief",
|
||||
"composer.formatting.list": "Lijst",
|
||||
"composer.formatting.strikethrough": "Doorhalen",
|
||||
"composer.formatting.link": "Link",
|
||||
"composer.formatting.picture": "Picture",
|
||||
"composer.upload-picture": "Upload Image",
|
||||
"composer.upload-file": "Upload File",
|
||||
"composer.formatting.picture": "Afbeelding",
|
||||
"composer.upload-picture": "Upload afbeelding",
|
||||
"composer.upload-file": "Upload bestand",
|
||||
"bootbox.ok": "OK",
|
||||
"bootbox.cancel": "Annuleren",
|
||||
"bootbox.confirm": "Bevestig",
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
"watch.title": "Krijg meldingen van nieuwe reacties op dit onderwerp",
|
||||
"unwatch.title": "Dit onderwerp niet langer volgen",
|
||||
"share_this_post": "Deel dit bericht",
|
||||
"watching": "Watching",
|
||||
"not-watching": "Not Watching",
|
||||
"ignoring": "Ignoring",
|
||||
"watching": "Gevolgd",
|
||||
"not-watching": "Niet gevolgd",
|
||||
"ignoring": "Genegeerd",
|
||||
"watching.description": "Notify me of new replies.<br/>Show topic in unread.",
|
||||
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
|
||||
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"invalid-password": "无效密码",
|
||||
"invalid-username-or-password": "请确认用户名和密码",
|
||||
"invalid-search-term": "无效的搜索关键字",
|
||||
"csrf-invalid": "We were unable to log you in, likely due to an expired session. Please try again",
|
||||
"csrf-invalid": "可能是由于会话过期,登录失败。请重试。",
|
||||
"invalid-pagination-value": "无效的分页数值,必须介于 %1 和 %2 之间",
|
||||
"username-taken": "此用户名已被占用",
|
||||
"email-taken": "此电子邮箱已被占用",
|
||||
@@ -23,7 +23,7 @@
|
||||
"no-email-to-confirm": "本论坛需要电子邮箱确认,请点击这里输入电子邮箱地址",
|
||||
"email-confirm-failed": "我们无法确认您的电子邮箱,请重试",
|
||||
"confirm-email-already-sent": "确认邮件已发出,如需重新发送请等待 %1 分钟后再试。",
|
||||
"sendmail-not-found": "The sendmail executable could not be found, please ensure it is installed and executable by the user running NodeBB.",
|
||||
"sendmail-not-found": "无法找到sendmail可执行程序,请确保sendmail已经安装并可被运行NodeBB的用户执行",
|
||||
"username-too-short": "用户名太短",
|
||||
"username-too-long": "用户名太长",
|
||||
"password-too-long": "密码太长",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"remember_me": "记住我?",
|
||||
"forgot_password": "忘记密码?",
|
||||
"alternative_logins": "使用合作网站帐号登录",
|
||||
"failed_login_attempt": "Login Unsuccessful",
|
||||
"failed_login_attempt": "登录失败",
|
||||
"login_successful": "您已经成功登录!",
|
||||
"dont_have_account": "没有帐号?"
|
||||
}
|
||||
@@ -29,14 +29,14 @@
|
||||
"composer.submit_and_lock": "提交并锁定",
|
||||
"composer.toggle_dropdown": "标为 Dropdown",
|
||||
"composer.uploading": "正在上传 %1",
|
||||
"composer.formatting.bold": "Bold",
|
||||
"composer.formatting.italic": "Italic",
|
||||
"composer.formatting.list": "List",
|
||||
"composer.formatting.strikethrough": "Strikethrough",
|
||||
"composer.formatting.link": "Link",
|
||||
"composer.formatting.picture": "Picture",
|
||||
"composer.upload-picture": "Upload Image",
|
||||
"composer.upload-file": "Upload File",
|
||||
"composer.formatting.bold": "加粗",
|
||||
"composer.formatting.italic": "倾斜",
|
||||
"composer.formatting.list": "列表",
|
||||
"composer.formatting.strikethrough": "删除线",
|
||||
"composer.formatting.link": "链接",
|
||||
"composer.formatting.picture": "图片",
|
||||
"composer.upload-picture": "上传图片",
|
||||
"composer.upload-file": "上传文件",
|
||||
"bootbox.ok": "确认",
|
||||
"bootbox.cancel": "取消",
|
||||
"bootbox.confirm": "确认",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"deleted_message": "此主题已被删除。只有拥有主题管理权限的用户可以查看。",
|
||||
"following_topic.message": "当有人回复此主题时,您会收到通知。",
|
||||
"not_following_topic.message": "您已停止接收此主题的通知。",
|
||||
"ignoring_topic.message": "You will no longer see this topic in the unread topics list. You will be notified when you are mentioned or your post is up voted.",
|
||||
"ignoring_topic.message": "您将不会在未读主题列表里看到这个主题,但在被提到以及帖子被顶时仍将收到通知。",
|
||||
"login_to_subscribe": "请注册或登录后,再订阅此主题。",
|
||||
"markAsUnreadForAll.success": "将全部主题标为未读。",
|
||||
"mark_unread": "标记为未读",
|
||||
@@ -42,12 +42,12 @@
|
||||
"watch.title": "当此主题有新回复时,通知我",
|
||||
"unwatch.title": "取消关注此主题",
|
||||
"share_this_post": "分享",
|
||||
"watching": "Watching",
|
||||
"not-watching": "Not Watching",
|
||||
"ignoring": "Ignoring",
|
||||
"watching.description": "Notify me of new replies.<br/>Show topic in unread.",
|
||||
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
|
||||
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
|
||||
"watching": "关注中",
|
||||
"not-watching": "未关注",
|
||||
"ignoring": "忽略中",
|
||||
"watching.description": "有新回复时通知我。<br/>在未读主题中显示。",
|
||||
"not-watching.description": "不要在有新回复时通知我。<br/>如果这个分类未被忽略则在未读主题中显示。",
|
||||
"ignoring.description": "不要在有新回复时通知我。<br/>不要在未读主题中显示该主题。",
|
||||
"thread_tools.title": "主题工具",
|
||||
"thread_tools.markAsUnreadForAll": "标记为未读",
|
||||
"thread_tools.pin": "置顶主题",
|
||||
|
||||
@@ -89,8 +89,8 @@
|
||||
"cant-delete-chat-message": "你不被允許刪除這條訊息",
|
||||
"already-voting-for-this-post": "你已經對這個張貼投過票了",
|
||||
"reputation-system-disabled": "信譽系統已停用。",
|
||||
"downvoting-disabled": "Downvoting已停用",
|
||||
"not-enough-reputation-to-downvote": "你沒有足夠的信譽downvote這個帖子",
|
||||
"downvoting-disabled": "反向投票已停用",
|
||||
"not-enough-reputation-to-downvote": "你沒有足夠的信譽可以對這個張貼進行反向投票",
|
||||
"not-enough-reputation-to-flag": "你沒有足夠的信譽來舉報這個帖子",
|
||||
"already-flagged": "你已經對這個張貼標記過了",
|
||||
"reload-failed": "NodeBB重載\"%1\"時遇到了問題。 NodeBB將繼續提供現有的客戶端資源,但請你撤消重載前的動作。",
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"default_picture": "預設圖示",
|
||||
"uploaded_picture": "已有頭像",
|
||||
"upload_new_picture": "上傳新頭像",
|
||||
"upload_new_picture_from_url": "上傳新頭像(URL)",
|
||||
"upload_new_picture_from_url": "從網址上傳新頭像",
|
||||
"current_password": "目前的密碼",
|
||||
"change_password": "更改密碼",
|
||||
"change_password_error": "無效的密碼!",
|
||||
@@ -72,7 +72,7 @@
|
||||
"digest_weekly": "每週",
|
||||
"digest_monthly": "每月",
|
||||
"send_chat_notifications": "如果有新的聊天消息而我不在線,發送郵件給我",
|
||||
"send_post_notifications": "Send an email when replies are made to topics I am subscribed to",
|
||||
"send_post_notifications": "當我訂閱的主題有新回覆時寄送Email給我",
|
||||
"settings-require-reload": "有些設定的更動是需要重新整理。點擊這裡來重新整理頁面。",
|
||||
"has_no_follower": "該用戶還沒有被任何人關注。",
|
||||
"follows_no_one": "該用戶還沒有關注過任何人。",
|
||||
@@ -102,10 +102,10 @@
|
||||
"select-skin": "選擇外觀",
|
||||
"select-homepage": "選擇首頁",
|
||||
"homepage": "首頁",
|
||||
"homepage_description": "選擇一個要用來當作討論區的首頁的頁面,或是選'None'來使用預設的首頁。",
|
||||
"homepage_description": "選擇一個要用來當作討論區的首頁的頁面,或是選None使用預設的首頁。",
|
||||
"custom_route": "自訂首頁路由",
|
||||
"custom_route_help": "在這裡輸入路由名稱,不需要在前面的斜線(例如\"recent\"或\"popular\")",
|
||||
"sso.title": "單一簽入(SSO)服務",
|
||||
"custom_route_help": "在這裡輸入路由名稱,不需要在前面的斜線(例如recent或popular)",
|
||||
"sso.title": "單一簽入SSO服務",
|
||||
"sso.associated": "關連於",
|
||||
"sso.not-associated": "點擊這裡進行關連於"
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
@import "./manage/categories";
|
||||
@import "./manage/tags";
|
||||
@import "./manage/groups";
|
||||
@import "./manage/registration";
|
||||
@import "./manage/users";
|
||||
@import "./appearance/customise";
|
||||
@import "./appearance/themes";
|
||||
@@ -18,6 +19,7 @@
|
||||
@import "./extend/rewards";
|
||||
@import "./advanced/database";
|
||||
@import "./advanced/logs";
|
||||
@import "./advanced/errors";
|
||||
@import "./settings";
|
||||
|
||||
@import "../flags";
|
||||
@@ -26,6 +28,11 @@
|
||||
@import "./modules/alerts";
|
||||
@import "./modules/selectable";
|
||||
@import "./modules/snackbar";
|
||||
@import "./modules/nprogress";
|
||||
|
||||
body {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.admin {
|
||||
background: #fff;
|
||||
|
||||
26
public/less/admin/advanced/errors.less
Normal file
26
public/less/admin/advanced/errors.less
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
.page-advanced-errors {
|
||||
.table {
|
||||
table-layout: fixed;
|
||||
|
||||
th {
|
||||
&:first-child {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
&:first-child {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,4 +89,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reconnect-spinner {
|
||||
left: initial;
|
||||
right: 310px;
|
||||
bottom: initial;
|
||||
top: 14px;
|
||||
}
|
||||
}
|
||||
7
public/less/admin/manage/registration.less
Normal file
7
public/less/admin/manage/registration.less
Normal file
@@ -0,0 +1,7 @@
|
||||
@media screen and (max-width: @screen-sm-max) {
|
||||
.page-manage-registration {
|
||||
.users-list {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
public/less/admin/modules/nprogress.less
Normal file
80
public/less/admin/modules/nprogress.less
Normal file
@@ -0,0 +1,80 @@
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: #29d;
|
||||
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
#nprogress .peg {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 10px #29d, 0 0 5px #29d;
|
||||
opacity: 1.0;
|
||||
|
||||
-webkit-transform: rotate(3deg) translate(0px, -4px);
|
||||
-ms-transform: rotate(3deg) translate(0px, -4px);
|
||||
transform: rotate(3deg) translate(0px, -4px);
|
||||
}
|
||||
|
||||
#nprogress .spinner {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 165px;
|
||||
right: 35px;
|
||||
}
|
||||
|
||||
@media (max-width: @screen-xs-max) {
|
||||
#nprogress .spinner {
|
||||
bottom: 15px;
|
||||
right: 15px;
|
||||
top: initial;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
box-sizing: border-box;
|
||||
|
||||
border: solid 2px transparent;
|
||||
border-top-color: #29d;
|
||||
border-left-color: #29d;
|
||||
border-radius: 50%;
|
||||
|
||||
-webkit-animation: nprogress-spinner 400ms linear infinite;
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent #nprogress .spinner,
|
||||
.nprogress-custom-parent #nprogress .bar {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@-webkit-keyframes nprogress-spinner {
|
||||
0% { -webkit-transform: rotate(0deg); }
|
||||
100% { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
/*global config, translator, componentHandler, define, socket, app, ajaxify, utils, bootbox, Slideout, RELATIVE_PATH*/
|
||||
/*global config, translator, componentHandler, define, socket, app, ajaxify, utils, bootbox, Slideout, NProgress, RELATIVE_PATH*/
|
||||
|
||||
(function() {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
app.alert = launchSnackbar;
|
||||
|
||||
configureSlidemenu();
|
||||
setupNProgress();
|
||||
});
|
||||
|
||||
$(window).on('action:ajaxify.contentLoaded', function(ev, data) {
|
||||
@@ -38,6 +39,16 @@
|
||||
componentHandler.upgradeDom();
|
||||
});
|
||||
|
||||
function setupNProgress() {
|
||||
$(window).on('action:ajaxify.start', function() {
|
||||
NProgress.set(0.7);
|
||||
});
|
||||
|
||||
$(window).on('action:ajaxify.end', function(ev, data) {
|
||||
NProgress.done();
|
||||
});
|
||||
}
|
||||
|
||||
function setupKeybindings() {
|
||||
require(['mousetrap'], function(mousetrap) {
|
||||
mousetrap.bind('ctrl+shift+a r', function() {
|
||||
|
||||
@@ -316,7 +316,7 @@ define('admin/manage/category', [
|
||||
autocomplete.user(inputEl, function(ev, ui) {
|
||||
socket.emit('admin.categories.setPrivilege', {
|
||||
cid: ajaxify.data.category.cid,
|
||||
privilege: ['find', 'read'],
|
||||
privilege: ['find', 'read', 'topics:read'],
|
||||
set: true,
|
||||
member: ui.item.user.uid
|
||||
}, function(err) {
|
||||
@@ -344,7 +344,7 @@ define('admin/manage/category', [
|
||||
autocomplete.group(inputEl, function(ev, ui) {
|
||||
socket.emit('admin.categories.setPrivilege', {
|
||||
cid: ajaxify.data.category.cid,
|
||||
privilege: ['groups:find', 'groups:read'],
|
||||
privilege: ['groups:find', 'groups:read', 'groups:topics:read'],
|
||||
set: true,
|
||||
member: ui.item.group.name
|
||||
}, function(err) {
|
||||
|
||||
@@ -120,6 +120,8 @@ define('forum/topic/threadTools', [
|
||||
type: 'success',
|
||||
timeout: 5000
|
||||
});
|
||||
|
||||
$(window).trigger('action:topics.changeWatching', {tid: tid, type: type});
|
||||
});
|
||||
|
||||
return false;
|
||||
|
||||
3
public/vendor/nprogress.min.js
vendored
Normal file
3
public/vendor/nprogress.min.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
|
||||
* @license MIT */
|
||||
!function(n,t){"object"==typeof exports?module.exports=t():n.NProgress=t()}(this,function(){function n(n,t,e){return t>n?t:n>e?e:n}function t(n){return 100*(-1+n)}function e(n,e,r){var i;return i="translate3d"===c.positionUsing?{transform:"translate3d("+t(n)+"%,0,0)"}:"translate"===c.positionUsing?{transform:"translate("+t(n)+"%,0)"}:{"margin-left":t(n)+"%"},i.transition="all "+e+"ms "+r,i}function r(n,t){var e="string"==typeof n?n:o(n);return e.indexOf(" "+t+" ")>=0}function i(n,t){var e=o(n),i=e+t;r(e,t)||(n.className=i.substring(1))}function s(n,t){var e,i=o(n);r(n,t)&&(e=i.replace(" "+t+" "," "),n.className=e.substring(1,e.length-1))}function o(n){return(" "+(n.className||"")+" ").replace(/\s+/gi," ")}function a(n){n&&n.parentNode&&n.parentNode.removeChild(n)}var u={};u.version="0.1.6";var c=u.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};u.configure=function(n){var t,e;for(t in n)e=n[t],void 0!==e&&n.hasOwnProperty(t)&&(c[t]=e);return this},u.status=null,u.set=function(t){var r=u.isStarted();t=n(t,c.minimum,1),u.status=1===t?null:t;var i=u.render(!r),s=i.querySelector(c.barSelector),o=c.speed,a=c.easing;return i.offsetWidth,l(function(n){""===c.positionUsing&&(c.positionUsing=u.getPositioningCSS()),f(s,e(t,o,a)),1===t?(f(i,{transition:"none",opacity:1}),i.offsetWidth,setTimeout(function(){f(i,{transition:"all "+o+"ms linear",opacity:0}),setTimeout(function(){u.remove(),n()},o)},o)):setTimeout(n,o)}),this},u.isStarted=function(){return"number"==typeof u.status},u.start=function(){u.status||u.set(0);var n=function(){setTimeout(function(){u.status&&(u.trickle(),n())},c.trickleSpeed)};return c.trickle&&n(),this},u.done=function(n){return n||u.status?u.inc(.3+.5*Math.random()).set(1):this},u.inc=function(t){var e=u.status;return e?("number"!=typeof t&&(t=(1-e)*n(Math.random()*e,.1,.95)),e=n(e+t,0,.994),u.set(e)):u.start()},u.trickle=function(){return u.inc(Math.random()*c.trickleRate)},function(){var n=0,t=0;u.promise=function(e){return e&&"resolved"!=e.state()?(0==t&&u.start(),n++,t++,e.always(function(){t--,0==t?(n=0,u.done()):u.set((n-t)/n)}),this):this}}(),u.render=function(n){if(u.isRendered())return document.getElementById("nprogress");i(document.documentElement,"nprogress-busy");var e=document.createElement("div");e.id="nprogress",e.innerHTML=c.template;var r,s=e.querySelector(c.barSelector),o=n?"-100":t(u.status||0),l=document.querySelector(c.parent);return f(s,{transition:"all 0 linear",transform:"translate3d("+o+"%,0,0)"}),c.showSpinner||(r=e.querySelector(c.spinnerSelector),r&&a(r)),l!=document.body&&i(l,"nprogress-custom-parent"),l.appendChild(e),e},u.remove=function(){s(document.documentElement,"nprogress-busy"),s(document.querySelector(c.parent),"nprogress-custom-parent");var n=document.getElementById("nprogress");n&&a(n)},u.isRendered=function(){return!!document.getElementById("nprogress")},u.getPositioningCSS=function(){var n=document.body.style,t="WebkitTransform"in n?"Webkit":"MozTransform"in n?"Moz":"msTransform"in n?"ms":"OTransform"in n?"O":"";return t+"Perspective"in n?"translate3d":t+"Transform"in n?"translate":"margin"};var l=function(){function n(){var e=t.shift();e&&e(n)}var t=[];return function(e){t.push(e),1==t.length&&n()}}(),f=function(){function n(n){return n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(n,t){return t.toUpperCase()})}function t(n){var t=document.body.style;if(n in t)return n;for(var e,r=i.length,s=n.charAt(0).toUpperCase()+n.slice(1);r--;)if(e=i[r]+s,e in t)return e;return n}function e(e){return e=n(e),s[e]||(s[e]=t(e))}function r(n,t,r){t=e(t),n.style[t]=r}var i=["Webkit","O","Moz","ms"],s={};return function(n,t){var e,i,s=arguments;if(2==s.length)for(e in t)i=t[e],void 0!==i&&t.hasOwnProperty(e)&&r(n,e,i);else r(n,s[1],s[2])}}();return u});
|
||||
@@ -48,7 +48,7 @@ module.exports = function(Categories) {
|
||||
function(data, next) {
|
||||
category = data.category;
|
||||
|
||||
var defaultPrivileges = ['find', 'read', 'topics:create', 'topics:reply'];
|
||||
var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply'];
|
||||
|
||||
async.series([
|
||||
async.apply(db.setObject, 'category:' + category.cid, category),
|
||||
@@ -57,7 +57,7 @@ module.exports = function(Categories) {
|
||||
async.apply(db.sortedSetAdd, 'cid:' + parentCid + ':children', category.order, category.cid),
|
||||
async.apply(privileges.categories.give, defaultPrivileges, category.cid, 'administrators'),
|
||||
async.apply(privileges.categories.give, defaultPrivileges, category.cid, 'registered-users'),
|
||||
async.apply(privileges.categories.give, ['find', 'read'], category.cid, 'guests')
|
||||
async.apply(privileges.categories.give, ['find', 'read', 'topics:read'], category.cid, 'guests')
|
||||
], next);
|
||||
},
|
||||
function(results, next) {
|
||||
@@ -97,14 +97,15 @@ module.exports = function(Categories) {
|
||||
destination = results.destination;
|
||||
|
||||
var tasks = [];
|
||||
if (copyParent && utils.isNumber(results.source.parentCid)) {
|
||||
tasks.push(async.apply(db.sortedSetAdd, 'cid:' + results.source.parentCid + ':children', results.source.order, toCid));
|
||||
}
|
||||
|
||||
if (copyParent && destination && utils.isNumber(destination.parentCid)) {
|
||||
|
||||
if (copyParent && utils.isNumber(destination.parentCid)) {
|
||||
tasks.push(async.apply(db.sortedSetRemove, 'cid:' + destination.parentCid + ':children', toCid));
|
||||
}
|
||||
|
||||
if (copyParent && utils.isNumber(results.source.parentCid)) {
|
||||
tasks.push(async.apply(db.sortedSetAdd, 'cid:' + results.source.parentCid + ':children', results.source.order, toCid));
|
||||
}
|
||||
|
||||
destination.description = results.source.description;
|
||||
destination.descriptionParsed = results.source.descriptionParsed;
|
||||
destination.icon = results.source.icon;
|
||||
@@ -133,7 +134,7 @@ module.exports = function(Categories) {
|
||||
|
||||
Categories.copyPrivilegesFrom = function(fromCid, toCid, callback) {
|
||||
var privilegeList = [
|
||||
'find', 'read', 'topics:create', 'topics:reply', 'purge', 'mods',
|
||||
'find', 'read', 'topics:create', 'topics:read', 'topics:reply', 'purge', 'mods',
|
||||
'groups:find', 'groups:read', 'groups:topics:create', 'groups:topics:reply', 'groups:purge', 'groups:moderate'
|
||||
];
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ var _ = require('underscore');
|
||||
var db = require('../database');
|
||||
var posts = require('../posts');
|
||||
var topics = require('../topics');
|
||||
var categories = require('../categories');
|
||||
var privileges = require('../privileges');
|
||||
|
||||
module.exports = function(Categories) {
|
||||
@@ -113,12 +114,26 @@ module.exports = function(Categories) {
|
||||
topic.teaserPid = topic.teaserPid || topic.mainPid;
|
||||
}
|
||||
});
|
||||
topics.getTeasers(_topicData, next);
|
||||
var cids = _topicData.map(function(topic) {
|
||||
return topic && topic.cid;
|
||||
}).filter(function(cid, index, array) {
|
||||
return cid && array.indexOf(cid) === index;
|
||||
});
|
||||
|
||||
async.parallel({
|
||||
categoryData: async.apply(categories.getCategoriesFields, cids, ['cid', 'parentCid']),
|
||||
teasers: async.apply(topics.getTeasers, _topicData),
|
||||
}, next);
|
||||
},
|
||||
function (teasers, next) {
|
||||
teasers.forEach(function(teaser, index) {
|
||||
function (results, next) {
|
||||
var parentCids = {};
|
||||
results.categoryData.forEach(function(category) {
|
||||
parentCids[category.cid] = category.parentCid;
|
||||
});
|
||||
results.teasers.forEach(function(teaser, index) {
|
||||
if (teaser) {
|
||||
teaser.cid = topicData[index].cid;
|
||||
teaser.parentCid = parseInt(parentCids[teaser.cid]) || 0;
|
||||
teaser.tid = teaser.uid = teaser.user.uid = undefined;
|
||||
teaser.topic = {
|
||||
slug: topicData[index].slug,
|
||||
@@ -126,8 +141,8 @@ module.exports = function(Categories) {
|
||||
};
|
||||
}
|
||||
});
|
||||
teasers = teasers.filter(Boolean);
|
||||
next(null, teasers);
|
||||
results.teasers = results.teasers.filter(Boolean);
|
||||
next(null, results.teasers);
|
||||
}
|
||||
], callback);
|
||||
}
|
||||
@@ -135,7 +150,8 @@ module.exports = function(Categories) {
|
||||
function assignTopicsToCategories(categories, topics) {
|
||||
categories.forEach(function(category) {
|
||||
category.posts = topics.filter(function(topic) {
|
||||
return topic.cid && parseInt(topic.cid, 10) === parseInt(category.cid, 10);
|
||||
return topic.cid && (parseInt(topic.cid, 10) === parseInt(category.cid, 10) ||
|
||||
parseInt(topic.parentCid, 10) === parseInt(category.cid, 10));
|
||||
}).sort(function(a, b) {
|
||||
return b.pid - a.pid;
|
||||
}).slice(0, parseInt(category.numRecentReplies, 10));
|
||||
|
||||
@@ -50,7 +50,7 @@ topicsController.get = function(req, res, callback) {
|
||||
|
||||
userPrivileges = results.privileges;
|
||||
|
||||
if (!userPrivileges.read || (parseInt(results.topic.deleted, 10) && !userPrivileges.view_deleted)) {
|
||||
if (!userPrivileges.read || !userPrivileges['topics:read'] || (parseInt(results.topic.deleted, 10) && !userPrivileges.view_deleted)) {
|
||||
return helpers.notAllowed(req, res);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,14 +57,16 @@ module.exports = function(Plugins) {
|
||||
);
|
||||
} else {
|
||||
// handle hook's startsWith, i.e. action:homepage.get
|
||||
var _parts = data.hook.split(':');
|
||||
_parts.pop();
|
||||
var _hook = _parts.join(':');
|
||||
if (Plugins.deprecatedHooksParams[_hook]) {
|
||||
winston.warn('[plugins/' + id + '] Hook `' + _hook + '` parameters: `' + Plugins.deprecatedHooksParams[_hook] + '`, are being deprecated, '
|
||||
+ 'all plugins should now use the `middleware/cls` module instead of hook\'s arguments to get a reference to the `req`, `res` and/or `socket` object(s) (from which you can get the current `uid` if you need to.) '
|
||||
+ '- for more info, visit https://docs.nodebb.org/en/latest/plugins/create.html#getting-a-reference-to-each-request-from-within-any-plugin-hook');
|
||||
delete Plugins.deprecatedHooksParams[_hook];
|
||||
var parts = data.hook.split(':');
|
||||
if (parts.length > 2) {
|
||||
parts.pop();
|
||||
}
|
||||
var hook = parts.join(':');
|
||||
if (Plugins.deprecatedHooksParams[hook]) {
|
||||
winston.warn('[plugins/' + id + '] Hook `' + hook + '` parameters: `' + Plugins.deprecatedHooksParams[hook] + '`, are being deprecated, '
|
||||
+ 'all plugins should now use the `middleware/cls` module instead of hook\'s arguments to get a reference to the `http-request` or the `socket-request` object(s) (from which you can get the current `uid` if you need to.) '
|
||||
+ '- for more info, visit https://docs.nodebb.org/en/latest/plugins/create.html#getting-a-reference-to-each-request-from-within-any-plugin-hook\n');
|
||||
delete Plugins.deprecatedHooksParams[hook];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,4 +198,4 @@ module.exports = function(Plugins) {
|
||||
Plugins.hasListeners = function(hook) {
|
||||
return !!(Plugins.loadedHooks[hook] && Plugins.loadedHooks[hook].length > 0);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var nconf = require('nconf'),
|
||||
url = require('url');
|
||||
var nconf = require('nconf');
|
||||
var url = require('url');
|
||||
var winston = require('winston');
|
||||
|
||||
var cache = require('./cache');
|
||||
var plugins = require('../plugins');
|
||||
@@ -50,21 +51,24 @@ module.exports = function(Posts) {
|
||||
// Turns relative links in post body to absolute urls
|
||||
var parsed, current, absolute;
|
||||
|
||||
while ((current=urlRegex.exec(content)) !== null) {
|
||||
while ((current = urlRegex.exec(content)) !== null) {
|
||||
if (current[1]) {
|
||||
parsed = url.parse(current[1]);
|
||||
try {
|
||||
parsed = url.parse(current[1]);
|
||||
if (!parsed.protocol) {
|
||||
if (current[1].startsWith('/')) {
|
||||
// Internal link
|
||||
absolute = nconf.get('url') + current[1];
|
||||
} else {
|
||||
// External link
|
||||
absolute = '//' + current[1];
|
||||
}
|
||||
|
||||
if (!parsed.protocol) {
|
||||
if (current[1].startsWith('/')) {
|
||||
// Internal link
|
||||
absolute = nconf.get('url') + current[1];
|
||||
} else {
|
||||
// External link
|
||||
absolute = '//' + current[1];
|
||||
content = content.slice(0, current.index + 6) + absolute + content.slice(current.index + 6 + current[1].length);
|
||||
}
|
||||
|
||||
content = content.slice(0, current.index + 6) + absolute + content.slice(current.index + 6 + current[1].length);
|
||||
}
|
||||
} catch(err) {
|
||||
winston.verbose(err.messsage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ module.exports = function(privileges) {
|
||||
// Method used in admin/category controller to show all users/groups with privs in that given cid
|
||||
|
||||
var privilegeLabels = [
|
||||
{name: 'Find category'},
|
||||
{name: 'Access & Read'},
|
||||
{name: 'Find Category'},
|
||||
{name: 'Access Category'},
|
||||
{name: 'Access Topics'},
|
||||
{name: 'Create Topics'},
|
||||
{name: 'Reply to Topics'},
|
||||
{name: 'Purge'},
|
||||
@@ -27,10 +28,10 @@ module.exports = function(privileges) {
|
||||
];
|
||||
|
||||
var userPrivilegeList = [
|
||||
'find', 'read', 'topics:create', 'topics:reply', 'purge', 'mods'
|
||||
'find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'purge', 'mods'
|
||||
];
|
||||
var groupPrivilegeList = [
|
||||
'groups:find', 'groups:read', 'groups:topics:create', 'groups:topics:reply', 'groups:purge', 'groups:moderate'
|
||||
'groups:find', 'groups:read', 'groups:topics:read', 'groups:topics:create', 'groups:topics:reply', 'groups:purge', 'groups:moderate'
|
||||
];
|
||||
|
||||
async.parallel({
|
||||
@@ -162,6 +163,9 @@ module.exports = function(privileges) {
|
||||
'topics:create': function(next) {
|
||||
helpers.isUserAllowedTo('topics:create', uid, [cid], next);
|
||||
},
|
||||
'topics:read': function(next) {
|
||||
helpers.isUserAllowedTo('topics:read', uid, [cid], next);
|
||||
},
|
||||
read: function(next) {
|
||||
helpers.isUserAllowedTo('read', uid, [cid], next);
|
||||
},
|
||||
@@ -182,6 +186,7 @@ module.exports = function(privileges) {
|
||||
cid: cid,
|
||||
uid: uid,
|
||||
'topics:create': results['topics:create'][0] || isAdminOrMod,
|
||||
'topics:read': results['topics:read'][0] || isAdminOrMod,
|
||||
editable: isAdminOrMod,
|
||||
view_deleted: isAdminOrMod,
|
||||
read: results.read[0] || isAdminOrMod,
|
||||
@@ -356,6 +361,9 @@ module.exports = function(privileges) {
|
||||
'topics:create': function(next) {
|
||||
groups.isMember(uid, 'cid:' + cid + ':privileges:topics:create', next);
|
||||
},
|
||||
'topics:read': function(next) {
|
||||
groups.isMember(uid, 'cid:' + cid + ':privileges:topics:read', next);
|
||||
},
|
||||
'topics:reply': function(next) {
|
||||
groups.isMember(uid, 'cid:' + cid + ':privileges:topics:reply', next);
|
||||
},
|
||||
@@ -376,6 +384,9 @@ module.exports = function(privileges) {
|
||||
},
|
||||
'groups:topics:reply': function(next) {
|
||||
groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:reply', next);
|
||||
},
|
||||
'groups:topics:read': function(next) {
|
||||
groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:read', next);
|
||||
}
|
||||
}, callback);
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@ module.exports = function(privileges) {
|
||||
topic = _topic;
|
||||
async.parallel({
|
||||
'topics:reply': async.apply(helpers.isUserAllowedTo, 'topics:reply', uid, [topic.cid]),
|
||||
'topics:read': async.apply(helpers.isUserAllowedTo, 'topics:read', uid, [topic.cid]),
|
||||
read: async.apply(helpers.isUserAllowedTo, 'read', uid, [topic.cid]),
|
||||
isOwner: function(next) {
|
||||
next(null, !!parseInt(uid, 10) && parseInt(uid, 10) === parseInt(topic.uid, 10));
|
||||
@@ -44,6 +45,7 @@ module.exports = function(privileges) {
|
||||
plugins.fireHook('filter:privileges.topics.get', {
|
||||
'topics:reply': (results['topics:reply'][0] && !locked) || isAdminOrMod,
|
||||
read: results.read[0] || isAdminOrMod,
|
||||
'topics:read': results['topics:read'][0] || isAdminOrMod,
|
||||
view_thread_tools: editable || deletable,
|
||||
editable: editable,
|
||||
deletable: deletable,
|
||||
|
||||
@@ -38,7 +38,7 @@ function generateForTopic(req, res, callback) {
|
||||
if (parseInt(results.topic.deleted, 10) && !results.privileges.view_deleted) {
|
||||
return callback();
|
||||
}
|
||||
if (!results.privileges.read) {
|
||||
if (!results.privileges.read || !results.privileges['topics:read']) {
|
||||
return helpers.notAllowed(req, res);
|
||||
}
|
||||
userPrivileges = results.privileges;
|
||||
|
||||
@@ -56,19 +56,19 @@ sitemap.getPages = function(callback) {
|
||||
var urls = [{
|
||||
url: '',
|
||||
changefreq: 'weekly',
|
||||
priority: '0.6'
|
||||
priority: 0.6
|
||||
}, {
|
||||
url: '/recent',
|
||||
changefreq: 'daily',
|
||||
priority: '0.4'
|
||||
priority: 0.4
|
||||
}, {
|
||||
url: '/users',
|
||||
changefreq: 'daily',
|
||||
priority: '0.4'
|
||||
priority: 0.4
|
||||
}, {
|
||||
url: '/groups',
|
||||
changefreq: 'daily',
|
||||
priority: '0.4'
|
||||
priority: 0.4
|
||||
}];
|
||||
|
||||
sitemap.maps.pages = sm.createSitemap({
|
||||
@@ -99,7 +99,7 @@ sitemap.getCategories = function(callback) {
|
||||
categoryUrls.push({
|
||||
url: '/category/' + category.slug,
|
||||
changefreq: 'weekly',
|
||||
priority: '0.4'
|
||||
priority: 0.4
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -153,7 +153,7 @@ sitemap.getTopicPage = function(page, callback) {
|
||||
url: '/topic/' + topic.slug,
|
||||
lastmodISO: utils.toISOString(topic.lastposttime),
|
||||
changefreq: 'daily',
|
||||
priority: '0.6'
|
||||
priority: 0.6
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -215,6 +215,10 @@ var cls = require('../middleware/cls');
|
||||
var referer = headers.referer || '';
|
||||
var data = ((payload || {}).data || []);
|
||||
|
||||
if (!host) {
|
||||
host = url.parse(referer).host;
|
||||
}
|
||||
|
||||
return {
|
||||
uid: socket.uid,
|
||||
params: data[1],
|
||||
|
||||
@@ -233,6 +233,8 @@ module.exports = function(Topics) {
|
||||
username: data.userData.username,
|
||||
userslug: data.userData.userslug,
|
||||
url: nconf.get('url') + '/topic/' + postData.topic.tid,
|
||||
topicSlug: postData.topic.slug,
|
||||
postCount: postData.topic.postcount,
|
||||
base_url: nconf.get('url')
|
||||
}, next);
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,7 @@ var db = require('./database'),
|
||||
schemaDate, thisSchemaDate,
|
||||
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
||||
latestSchema = Date.UTC(2016, 3, 29);
|
||||
latestSchema = Date.UTC(2016, 4, 28);
|
||||
|
||||
Upgrade.check = function(callback) {
|
||||
db.get('schemaDate', function(err, value) {
|
||||
@@ -494,6 +494,75 @@ Upgrade.upgrade = function(callback) {
|
||||
winston.info('[2016/04/29] Dismiss flags from deleted topics skipped!');
|
||||
next();
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
thisSchemaDate = Date.UTC(2016, 4, 28);
|
||||
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
updatesMade = true;
|
||||
winston.info('[2016/05/28] Giving topics:read privs to any group that was previously allowed to Find & Access Category');
|
||||
|
||||
var groupsAPI = require('./groups');
|
||||
var privilegesAPI = require('./privileges');
|
||||
|
||||
db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) {
|
||||
async.eachSeries(cids, function(cid, next) {
|
||||
privilegesAPI.categories.list(cid, function(err, data) {
|
||||
var groups = data.groups;
|
||||
var users = data.users;
|
||||
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
async.eachSeries(groups, function(group, next) {
|
||||
if (group.privileges['groups:read']) {
|
||||
return groupsAPI.join('cid:' + cid + ':privileges:groups:topics:read', group.name, function(err) {
|
||||
if (!err) {
|
||||
winston.info('cid:' + cid + ':privileges:groups:topics:read granted to gid: ' + group.name);
|
||||
}
|
||||
|
||||
return next(err);
|
||||
});
|
||||
}
|
||||
|
||||
next(null);
|
||||
}, next);
|
||||
},
|
||||
function(next) {
|
||||
async.eachSeries(users, function(user, next) {
|
||||
if (user.privileges['read']) {
|
||||
return groupsAPI.join('cid:' + cid + ':privileges:topics:read', user.uid, function(err) {
|
||||
if (!err) {
|
||||
winston.info('cid:' + cid + ':privileges:topics:read granted to uid: ' + user.uid);
|
||||
}
|
||||
|
||||
return next(err);
|
||||
});
|
||||
}
|
||||
|
||||
next(null);
|
||||
}, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (!err) {
|
||||
winston.info('-- cid ' + cid + ' upgraded');
|
||||
}
|
||||
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
winston.info('[2016/05/28] Giving topics:read privs to any group that was previously allowed to Find & Access Category - done');
|
||||
Upgrade.update(thisSchemaDate, next);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
winston.info('[2016/05/28] Giving topics:read privs to any group that was previously allowed to Find & Access Category - skipped!');
|
||||
next();
|
||||
}
|
||||
}
|
||||
// Add new schema updates here
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 24!!!
|
||||
|
||||
@@ -68,10 +68,4 @@
|
||||
|
||||
<button id="save" class="floating-button mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
|
||||
<i class="material-icons">save</i>
|
||||
</button>
|
||||
|
||||
<script>
|
||||
require(['admin/settings'], function(Settings) {
|
||||
Settings.init();
|
||||
});
|
||||
</script>
|
||||
</button>
|
||||
@@ -54,6 +54,7 @@
|
||||
<script type="text/javascript" src="{relative_path}/vendor/jquery/js/jquery-ui-1.10.4.custom.js?{cache-buster}"></script>
|
||||
<script type="text/javascript" src="{relative_path}/vendor/snackbar/snackbar.min.js?{cache-buster}"></script>
|
||||
<script type="text/javascript" src="{relative_path}/vendor/slideout/slideout.min.js?{cache-buster}"></script>
|
||||
<script type="text/javascript" src="{relative_path}/vendor/nprogress.min.js?{cache-buster}"></script>
|
||||
|
||||
<!-- BEGIN scripts -->
|
||||
<script type="text/javascript" src="{scripts.src}"></script>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<!-- IF !users.length -->
|
||||
<p class="panel-body">
|
||||
There are no users in the registration queue. <br>
|
||||
To enable this feature, go to <a href="{config.relative_path}/admin/settings/user">Settings -> User -> Authentication</a> and set
|
||||
To enable this feature, go to <a href="{config.relative_path}/admin/settings/user">Settings → User → Authentication</a> and set
|
||||
<strong>Registration Type</strong> to "Admin Approval".
|
||||
</p>
|
||||
<!-- ENDIF !users.length -->
|
||||
@@ -13,8 +13,8 @@
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>IP</th>
|
||||
<th>Time</th>
|
||||
<th class="hidden-xs">IP</th>
|
||||
<th class="hidden-xs">Time</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<!-- BEGIN users -->
|
||||
@@ -35,7 +35,7 @@
|
||||
<!-- ENDIF users.emailSpam -->
|
||||
{users.email}
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
<!-- IF users.ipSpam -->
|
||||
<i class="fa fa-times-circle text-danger" title="Frequency: {users.spamData.ip.frequency} Appears: {users.spamData.ip.appears}"></i>
|
||||
<!-- ELSE -->
|
||||
@@ -43,7 +43,7 @@
|
||||
<!-- ENDIF users.ipSpam -->
|
||||
{users.ip}
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
<span class="timeago" title="{users.timestampISO}"></span>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
Privileges <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li role="presentation"><a href="#" data-priv="groups:find" class="<!-- IF groups.privileges.groups:find -->active<!-- ENDIF groups.privileges.groups:find -->">Find category</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="groups:read" class="<!-- IF groups.privileges.groups:read -->active<!-- ENDIF groups.privileges.groups:read -->">Access & Read</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="groups:find" class="<!-- IF groups.privileges.groups:find -->active<!-- ENDIF groups.privileges.groups:find -->">Find Category</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="groups:read" class="<!-- IF groups.privileges.groups:read -->active<!-- ENDIF groups.privileges.groups:read -->">Access Category</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="groups:topics:read" class="<!-- IF groups.privileges.groups:topics:read -->active<!-- ENDIF groups.privileges.groups:topics:read -->">Access Topics</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="groups:topics:create" class="<!-- IF groups.privileges.groups:topics:create -->active<!-- ENDIF groups.privileges.groups:topics:create -->">Create Topics</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="groups:topics:reply" class="<!-- IF groups.privileges.groups:topics:reply -->active<!-- ENDIF groups.privileges.groups:topics:reply -->">Reply to Topics</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
Privileges <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li role="presentation"><a href="#" data-priv="find" class="<!-- IF users.privileges.find -->active<!-- ENDIF users.privileges.find -->">Find category</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="read" class="<!-- IF users.privileges.read -->active<!-- ENDIF users.privileges.read -->">Access & Read</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="find" class="<!-- IF users.privileges.find -->active<!-- ENDIF users.privileges.find -->">Find Category</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="read" class="<!-- IF users.privileges.read -->active<!-- ENDIF users.privileges.read -->">Access Category</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="topics:read" class="<!-- IF users.privileges.topics:read -->active<!-- ENDIF users.privileges.topics:read -->">Access Topics</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="topics:create" class="<!-- IF users.privileges.topics:create -->active<!-- ENDIF users.privileges.topics:create -->">Create Topics</a></li>
|
||||
<li role="presentation"><a href="#" data-priv="topics:reply" class="<!-- IF users.privileges.topics:reply -->active<!-- ENDIF users.privileges.topics:reply -->">Reply to Topics</a></li>
|
||||
<li role="presentation" class="divider"></li>
|
||||
|
||||
@@ -256,4 +256,12 @@
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right hidden-xs reconnect-spinner">
|
||||
<li>
|
||||
<a href="#" id="reconnect" class="hide" title="Connection to {title} has been lost, attempting to reconnect...">
|
||||
<i class="fa fa-check"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
Reference in New Issue
Block a user