mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-09 15:35:47 +01:00
Merge branch 'develop' into activitypub
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
"ip": "رقم الآي بي <strong> %1 </strong>",
|
||||
"nodes-responded": "عدد %1 نقطة/نقاط استجابوا خلال %2 جزء من الثانية.",
|
||||
"host": "المضيف",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 възела отговориха в рамките на %2мсек!",
|
||||
"host": "сървър",
|
||||
"primary": "основен / изпълнение на задачите",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "ид. на процеса",
|
||||
"nodejs": "nodejs",
|
||||
"online": "на линия",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Регистрирани",
|
||||
"sockets": "Сокети",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Гости",
|
||||
|
||||
"info": "Информация"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 vazeb odpovědělo během %2ms.",
|
||||
"host": "host",
|
||||
"primary": "primární / spuštěné úlohy",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "připojen",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registrován",
|
||||
"sockets": "Sockety",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Hosté",
|
||||
|
||||
"info": "Informace"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP<strong>%1</strong>",
|
||||
"nodes-responded": "%1 Knoten antworteten innerhalb von %2ms",
|
||||
"host": "Host",
|
||||
"primary": "Primärer / Laufjob",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "PID",
|
||||
"nodejs": "Node.js Version",
|
||||
"online": "Online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registriert",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Gäste",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "¡%1 nodos respondieron en %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "en-linea",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registrado",
|
||||
"sockets": "Toma",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Invitados",
|
||||
|
||||
"info": "Información"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 noeuds ont répondu en %2ms !",
|
||||
"host": "hôte",
|
||||
"primary": "Tâches principales / Exécuter",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "en ligne",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Enregistré",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Invités",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 צמתים הגיבו בתוך %2מילי שניות!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "מקוון",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "רשום",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "אורחים",
|
||||
|
||||
"info": "מידע"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "Domaćin",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "Na mreži",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registriran",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Gosti",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 csomópont válaszolt %2mp-n belül!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Regisztrált",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Vendégek",
|
||||
|
||||
"info": "Információ"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": " IP % 1",
|
||||
"nodes-responded": "%1 հանգույցներ արձագանքեցին %2ms-ի սահմաններում:",
|
||||
"host": "host",
|
||||
"primary": "առաջնային / գործարկվող աշխատատեղեր",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "առցանց",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Գրանցված",
|
||||
"sockets": "Վարդակներ",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Հյուրեր",
|
||||
|
||||
"info": "տեղեկատվություն"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodi hanno risposto entro %2ms!",
|
||||
"host": "host",
|
||||
"primary": "processi primari/eseguiti",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registrato",
|
||||
"sockets": "Socket",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Ospiti",
|
||||
|
||||
"info": "Informazioni"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1ノードは%2ms以内に応答しました!",
|
||||
"host": "ホスト",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "オンライン",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "登録数",
|
||||
"sockets": "ソケット数",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "ゲスト数",
|
||||
|
||||
"info": "情報"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1개의 노드가 %2밀리초 안에 응답했습니다!",
|
||||
"host": "호스트",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "PID",
|
||||
"nodejs": "Node.js",
|
||||
"online": "온라인",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "소켓",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "비회원",
|
||||
|
||||
"info": "정보"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 serveri atbildēja %2ms laikā!",
|
||||
"host": "serveris",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "tiešsaistē",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Reģistrētie",
|
||||
"sockets": "Tīkla savienojumi",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Viesi",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Geregistreerd",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Gasten",
|
||||
|
||||
"info": "Informatie"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 maszyn odpowiedziało w ciągu %2ms!",
|
||||
"host": "host",
|
||||
"primary": "główne / uruchomione zadania",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "dostępny",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Zarejestrowane",
|
||||
"sockets": "Sockety",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Goście",
|
||||
|
||||
"info": "Informacja"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes respondidos dentro de %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registrado",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Visitantes",
|
||||
|
||||
"info": "Informação"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nós responderam dentro de %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registados",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Convidados",
|
||||
|
||||
"info": "Informação"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "Узлов: %1. Время ответа %2мс!",
|
||||
"host": "хост",
|
||||
"primary": "первичный",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "онлайн",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Авторизованных",
|
||||
"sockets": "Сокеты",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Гостей",
|
||||
|
||||
"info": "Сырые данные"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 väzieb odpovedalo počas %2ms.",
|
||||
"host": "hosť",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "pripojený",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registrovaný",
|
||||
"sockets": "Sockety",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Hostia",
|
||||
|
||||
"info": "Informácie"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 vozlišč se je odzvalo v %2ms!",
|
||||
"host": "gostitelj",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "na spletu",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registrirani",
|
||||
"sockets": "Vtičnice",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Gostje",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes responded within %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Registered",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Guests",
|
||||
|
||||
"info": "Info"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nodes ตอบสนองแล้วภายใน %2ms!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "ลงทะเบียนแล้ว",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "ผู้เยี่ยมเยียน",
|
||||
|
||||
"info": "ข้อมูล"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%2ms içinde %1 düğüm yanıt verdi!",
|
||||
"host": "sunucu",
|
||||
"primary": "ana sunucu / işlemleri gerçekleştir",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "çevrimiçi",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Kayıtlı",
|
||||
"sockets": "Soketler",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Ziyaretçiler",
|
||||
|
||||
"info": "Bilgi"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 вузлів відповіли за %2мс!",
|
||||
"host": "host",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "online",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Зареєстровано",
|
||||
"sockets": "Сокети",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Гостей",
|
||||
|
||||
"info": "Інфо"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1 nút đã phản hồi trong %2ms!",
|
||||
"host": "máy chủ",
|
||||
"primary": "công việc chính/điều hành",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "trực tuyến",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "Đã đăng ký",
|
||||
"sockets": "Sockets",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "Khách",
|
||||
|
||||
"info": "Thông tin"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1个节点在%2ms内响应!",
|
||||
"host": "主机",
|
||||
"primary": "主/运行任务",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "在线",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "已注册",
|
||||
"sockets": "接口",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "游客",
|
||||
|
||||
"info": "信息"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"ip": "IP <strong>%1</strong>",
|
||||
"nodes-responded": "%1個節點在%2ms內響應!",
|
||||
"host": "主機",
|
||||
"primary": "primary / run jobs",
|
||||
"primary": "primary / jobs",
|
||||
"pid": "pid",
|
||||
"nodejs": "nodejs",
|
||||
"online": "在線",
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
"registered": "已註冊",
|
||||
"sockets": "網路接口",
|
||||
"connection-count": "Connection Count",
|
||||
"guests": "訪客",
|
||||
|
||||
"info": "資訊"
|
||||
|
||||
@@ -331,6 +331,12 @@ UserObjectFull:
|
||||
example:
|
||||
- administrators
|
||||
- Staff
|
||||
iconBackgrounds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: A valid CSS colour code
|
||||
example: '#fff'
|
||||
muted:
|
||||
type: boolean
|
||||
description: Whether or not the user has been muted.
|
||||
|
||||
@@ -152,12 +152,6 @@ get:
|
||||
type: boolean
|
||||
enableQuickReply:
|
||||
type: boolean
|
||||
iconBackgrounds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: A valid CSS colour code
|
||||
example: '#fff'
|
||||
emailPrompt:
|
||||
type: number
|
||||
useragent:
|
||||
|
||||
@@ -116,6 +116,8 @@ get:
|
||||
type: number
|
||||
socketCount:
|
||||
type: number
|
||||
connectionCount:
|
||||
type: number
|
||||
users:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -152,12 +152,6 @@ get:
|
||||
type: boolean
|
||||
enableQuickReply:
|
||||
type: boolean
|
||||
iconBackgrounds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: A valid CSS colour code
|
||||
example: '#fff'
|
||||
emailPrompt:
|
||||
type: number
|
||||
useragent:
|
||||
|
||||
@@ -27,7 +27,7 @@ define('accounts/picture', [
|
||||
icon: { text: ajaxify.data['icon:text'], bgColor: ajaxify.data['icon:bgColor'] },
|
||||
defaultAvatar: ajaxify.data.defaultAvatar,
|
||||
allowProfileImageUploads: ajaxify.data.allowProfileImageUploads,
|
||||
iconBackgrounds: config.iconBackgrounds,
|
||||
iconBackgrounds: ajaxify.data.iconBackgrounds,
|
||||
user: {
|
||||
uid: ajaxify.data.uid,
|
||||
username: ajaxify.data.username,
|
||||
|
||||
@@ -640,7 +640,7 @@ usersAPI.changePicture = async (caller, data) => {
|
||||
picture = returnData && returnData.picture;
|
||||
}
|
||||
|
||||
const validBackgrounds = await user.getIconBackgrounds(caller.uid);
|
||||
const validBackgrounds = await user.getIconBackgrounds();
|
||||
if (!validBackgrounds.includes(data.bgColor)) {
|
||||
data.bgColor = validBackgrounds[0];
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ blocksController.getBlocks = async function (req, res) {
|
||||
const resultsPerPage = 50;
|
||||
const start = Math.max(0, page - 1) * resultsPerPage;
|
||||
const stop = start + resultsPerPage - 1;
|
||||
const payload = res.locals.userData;
|
||||
const { uid, username, userslug, blocksCount } = payload;
|
||||
|
||||
const { uid, username, userslug, blocksCount } = await user.getUserFields(res.locals.uid, ['uid', 'username', 'userslug', 'blocksCount']);
|
||||
const payload = {};
|
||||
const uids = await user.blocks.list(uid);
|
||||
const data = await plugins.hooks.fire('filter:user.getBlocks', {
|
||||
uids: uids,
|
||||
|
||||
@@ -9,7 +9,8 @@ const meta = require('../../meta');
|
||||
const categoriesController = module.exports;
|
||||
|
||||
categoriesController.get = async function (req, res) {
|
||||
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
|
||||
const payload = res.locals.userData;
|
||||
const { username, userslug } = payload;
|
||||
const [states, allCategoriesData] = await Promise.all([
|
||||
user.getCategoryWatchState(res.locals.uid),
|
||||
categories.buildForSelect(res.locals.uid, 'find', ['descriptionParsed', 'depth', 'slug']),
|
||||
@@ -31,7 +32,6 @@ categoriesController.get = async function (req, res) {
|
||||
}
|
||||
});
|
||||
|
||||
const payload = {};
|
||||
payload.categories = categoriesData;
|
||||
payload.title = `[[pages:account/watched-categories, ${username}]]`;
|
||||
payload.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
const db = require('../../database');
|
||||
const meta = require('../../meta');
|
||||
const user = require('../../user');
|
||||
const helpers = require('../helpers');
|
||||
|
||||
const consentController = module.exports;
|
||||
@@ -11,11 +10,10 @@ consentController.get = async function (req, res, next) {
|
||||
if (!meta.config.gdpr_enabled) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
|
||||
const payload = res.locals.userData;
|
||||
const { username, userslug } = payload;
|
||||
const consented = await db.getObjectField(`user:${res.locals.uid}`, 'gdpr_consent');
|
||||
|
||||
const payload = {};
|
||||
payload.gdpr_consent = parseInt(consented, 10) === 1;
|
||||
payload.digest = {
|
||||
frequency: meta.config.dailyDigestFreq || 'off',
|
||||
|
||||
@@ -6,13 +6,16 @@ const helpers = require('../helpers');
|
||||
const groups = require('../../groups');
|
||||
const privileges = require('../../privileges');
|
||||
const plugins = require('../../plugins');
|
||||
const accountHelpers = require('./helpers');
|
||||
const file = require('../../file');
|
||||
|
||||
const editController = module.exports;
|
||||
|
||||
editController.get = async function (req, res) {
|
||||
const [{
|
||||
editController.get = async function (req, res, next) {
|
||||
const { userData } = res.locals;
|
||||
if (!userData) {
|
||||
return next();
|
||||
}
|
||||
const {
|
||||
username,
|
||||
userslug,
|
||||
isSelf,
|
||||
@@ -20,36 +23,36 @@ editController.get = async function (req, res) {
|
||||
groups: _groups,
|
||||
groupTitleArray,
|
||||
allowMultipleBadges,
|
||||
}, canUseSignature, canManageUsers] = await Promise.all([
|
||||
accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query),
|
||||
} = userData;
|
||||
|
||||
const [canUseSignature, canManageUsers] = await Promise.all([
|
||||
privileges.global.can('signature', req.uid),
|
||||
privileges.admin.can('admin:users', req.uid),
|
||||
]);
|
||||
|
||||
const payload = {};
|
||||
payload.maximumSignatureLength = meta.config.maximumSignatureLength;
|
||||
payload.maximumAboutMeLength = meta.config.maximumAboutMeLength;
|
||||
payload.maximumProfileImageSize = meta.config.maximumProfileImageSize;
|
||||
payload.allowMultipleBadges = meta.config.allowMultipleBadges === 1;
|
||||
payload.allowAccountDelete = meta.config.allowAccountDelete === 1;
|
||||
payload.allowWebsite = !isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:website'];
|
||||
payload.allowAboutMe = !isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:aboutme'];
|
||||
payload.allowSignature = canUseSignature && (!isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:signature']);
|
||||
payload.profileImageDimension = meta.config.profileImageDimension;
|
||||
payload.defaultAvatar = user.getDefaultAvatar();
|
||||
userData.maximumSignatureLength = meta.config.maximumSignatureLength;
|
||||
userData.maximumAboutMeLength = meta.config.maximumAboutMeLength;
|
||||
userData.maximumProfileImageSize = meta.config.maximumProfileImageSize;
|
||||
userData.allowMultipleBadges = meta.config.allowMultipleBadges === 1;
|
||||
userData.allowAccountDelete = meta.config.allowAccountDelete === 1;
|
||||
userData.allowWebsite = !isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:website'];
|
||||
userData.allowAboutMe = !isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:aboutme'];
|
||||
userData.allowSignature = canUseSignature && (!isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:signature']);
|
||||
userData.profileImageDimension = meta.config.profileImageDimension;
|
||||
userData.defaultAvatar = user.getDefaultAvatar();
|
||||
|
||||
payload.groups = _groups.filter(g => g && g.userTitleEnabled && !groups.isPrivilegeGroup(g.name) && g.name !== 'registered-users');
|
||||
userData.groups = _groups.filter(g => g && g.userTitleEnabled && !groups.isPrivilegeGroup(g.name) && g.name !== 'registered-users');
|
||||
|
||||
if (req.uid === res.locals.uid || canManageUsers) {
|
||||
const { associations } = await plugins.hooks.fire('filter:auth.list', { uid: res.locals.uid, associations: [] });
|
||||
payload.sso = associations;
|
||||
userData.sso = associations;
|
||||
}
|
||||
|
||||
if (!allowMultipleBadges) {
|
||||
payload.groupTitle = groupTitleArray[0];
|
||||
userData.groupTitle = groupTitleArray[0];
|
||||
}
|
||||
|
||||
payload.groups.sort((a, b) => {
|
||||
userData.groups.sort((a, b) => {
|
||||
const i1 = groupTitleArray.indexOf(a.name);
|
||||
const i2 = groupTitleArray.indexOf(b.name);
|
||||
if (i1 === -1) {
|
||||
@@ -59,14 +62,14 @@ editController.get = async function (req, res) {
|
||||
}
|
||||
return i1 - i2;
|
||||
});
|
||||
payload.groups.forEach((group) => {
|
||||
userData.groups.forEach((group) => {
|
||||
group.userTitle = group.userTitle || group.displayName;
|
||||
group.selected = groupTitleArray.includes(group.name);
|
||||
});
|
||||
payload.groupSelectSize = Math.min(10, Math.max(5, payload.groups.length + 1));
|
||||
userData.groupSelectSize = Math.min(10, Math.max(5, userData.groups.length + 1));
|
||||
|
||||
payload.title = `[[pages:account/edit, ${username}]]`;
|
||||
payload.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
userData.title = `[[pages:account/edit, ${username}]]`;
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
{
|
||||
text: username,
|
||||
url: `/user/${userslug}`,
|
||||
@@ -75,9 +78,9 @@ editController.get = async function (req, res) {
|
||||
text: '[[user:edit]]',
|
||||
},
|
||||
]);
|
||||
payload.editButtons = [];
|
||||
userData.editButtons = [];
|
||||
|
||||
res.render('account/edit', payload);
|
||||
res.render('account/edit', userData);
|
||||
};
|
||||
|
||||
editController.password = async function (req, res, next) {
|
||||
@@ -102,6 +105,7 @@ editController.email = async function (req, res, next) {
|
||||
};
|
||||
|
||||
async function renderRoute(name, req, res) {
|
||||
const { userData } = res.locals;
|
||||
const [isAdmin, { username, userslug }, hasPassword] = await Promise.all([
|
||||
privileges.admin.can('admin:users', req.uid),
|
||||
user.getUserFields(res.locals.uid, ['username', 'userslug']),
|
||||
@@ -112,14 +116,14 @@ async function renderRoute(name, req, res) {
|
||||
return helpers.notAllowed(req, res);
|
||||
}
|
||||
|
||||
const payload = { hasPassword };
|
||||
userData.hasPassword = hasPassword;
|
||||
if (name === 'password') {
|
||||
payload.minimumPasswordLength = meta.config.minimumPasswordLength;
|
||||
payload.minimumPasswordStrength = meta.config.minimumPasswordStrength;
|
||||
userData.minimumPasswordLength = meta.config.minimumPasswordLength;
|
||||
userData.minimumPasswordStrength = meta.config.minimumPasswordStrength;
|
||||
}
|
||||
|
||||
payload.title = `[[pages:account/edit/${name}, ${username}]]`;
|
||||
payload.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
userData.title = `[[pages:account/edit/${name}, ${username}]]`;
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
{
|
||||
text: username,
|
||||
url: `/user/${userslug}`,
|
||||
@@ -133,7 +137,7 @@ async function renderRoute(name, req, res) {
|
||||
},
|
||||
]);
|
||||
|
||||
res.render(`account/edit/${name}`, payload);
|
||||
res.render(`account/edit/${name}`, userData);
|
||||
}
|
||||
|
||||
editController.uploadPicture = async function (req, res, next) {
|
||||
|
||||
@@ -15,18 +15,16 @@ followController.getFollowers = async function (req, res, next) {
|
||||
};
|
||||
|
||||
async function getFollow(tpl, name, req, res) {
|
||||
const { userData: payload } = res.locals;
|
||||
const {
|
||||
username, userslug, followerCount, followingCount,
|
||||
} = await user.getUserFields(res.locals.uid, [
|
||||
'username', 'userslug', 'followerCount', 'followingCount',
|
||||
]);
|
||||
} = payload;
|
||||
|
||||
const page = parseInt(req.query.page, 10) || 1;
|
||||
const resultsPerPage = 50;
|
||||
const start = Math.max(0, page - 1) * resultsPerPage;
|
||||
const stop = start + resultsPerPage - 1;
|
||||
|
||||
const payload = {};
|
||||
payload.title = `[[pages:${tpl}, ${username}]]`;
|
||||
|
||||
const method = name === 'following' ? 'getFollowing' : 'getFollowers';
|
||||
|
||||
@@ -9,7 +9,7 @@ const groupsController = module.exports;
|
||||
groupsController.get = async function (req, res) {
|
||||
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
|
||||
|
||||
const payload = {};
|
||||
const payload = res.locals.userData;
|
||||
|
||||
let groupsData = await groups.getUserGroups([res.locals.uid]);
|
||||
groupsData = groupsData[0];
|
||||
|
||||
@@ -40,11 +40,7 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID, query = {})
|
||||
await parseAboutMe(results.userData);
|
||||
|
||||
let { userData } = results;
|
||||
const { userSettings } = results;
|
||||
const { isAdmin } = results;
|
||||
const { isGlobalModerator } = results;
|
||||
const { isModerator } = results;
|
||||
const { canViewInfo } = results;
|
||||
const { userSettings, isAdmin, isGlobalModerator, isModerator, canViewInfo } = results;
|
||||
const isSelf = parseInt(callerUID, 10) === parseInt(userData.uid, 10);
|
||||
|
||||
if (meta.config['reputation:disabled']) {
|
||||
@@ -93,6 +89,7 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID, query = {})
|
||||
userData.isFollowing = results.isFollowing;
|
||||
userData.canChat = results.canChat;
|
||||
userData.hasPrivateChat = results.hasPrivateChat;
|
||||
userData.iconBackgrounds = results.iconBackgrounds;
|
||||
userData.showHidden = results.canEdit; // remove in v1.19.0
|
||||
userData.allowProfilePicture = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:profile-picture'];
|
||||
userData.allowCoverPicture = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:cover-picture'];
|
||||
@@ -169,6 +166,7 @@ async function getAllData(uid, callerUID) {
|
||||
canViewInfo: privileges.global.can('view:users:info', callerUID),
|
||||
canChat: canChat(callerUID, uid),
|
||||
hasPrivateChat: messaging.hasPrivateChat(callerUID, uid),
|
||||
iconBackgrounds: user.getIconBackgrounds(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,19 +13,17 @@ infoController.get = async function (req, res) {
|
||||
const start = (page - 1) * itemsPerPage;
|
||||
const stop = start + itemsPerPage - 1;
|
||||
|
||||
const [{ username, userslug }, isPrivileged] = await Promise.all([
|
||||
user.getUserFields(res.locals.uid, ['username', 'userslug']),
|
||||
const payload = res.locals.userData;
|
||||
const { username, userslug } = payload;
|
||||
const [isPrivileged, history, sessions, usernames, emails] = await Promise.all([
|
||||
user.isPrivileged(req.uid),
|
||||
]);
|
||||
const [history, sessions, usernames, emails, notes] = await Promise.all([
|
||||
user.getModerationHistory(res.locals.uid),
|
||||
user.auth.getSessions(res.locals.uid, req.sessionID),
|
||||
user.getHistory(`user:${res.locals.uid}:usernames`),
|
||||
user.getHistory(`user:${res.locals.uid}:emails`),
|
||||
getNotes({ uid: res.locals.uid, isPrivileged }, start, stop),
|
||||
]);
|
||||
|
||||
const payload = {};
|
||||
const notes = await getNotes({ uid: res.locals.uid, isPrivileged }, start, stop);
|
||||
|
||||
payload.history = history;
|
||||
payload.sessions = sessions;
|
||||
|
||||
@@ -177,16 +177,16 @@ async function getPostsFromUserSet(template, req, res) {
|
||||
const data = templateToData[template];
|
||||
const page = Math.max(1, parseInt(req.query.page, 10) || 1);
|
||||
|
||||
// exposeUid returns -2 for all remote users for ease of processing, restoring uid
|
||||
let { uid } = res.locals;
|
||||
if (uid === -2) {
|
||||
uid = await db.getObjectField('handle:uid', req.params.userslug.toLowerCase());
|
||||
}
|
||||
|
||||
const [{ username, userslug }, settings] = await Promise.all([
|
||||
user.getUserFields(uid, ['username', 'userslug']),
|
||||
user.getSettings(req.uid),
|
||||
]);
|
||||
const payload = res.locals.userData;
|
||||
const { username, userslug } = uid === -2 ?
|
||||
await user.getUserFields(uid, ['username', 'userslug']) :
|
||||
payload;
|
||||
const settings = await user.getSettings(req.uid);
|
||||
|
||||
const itemsPerPage = data.type === 'topics' ? settings.topicsPerPage : settings.postsPerPage;
|
||||
const start = (page - 1) * itemsPerPage;
|
||||
@@ -213,7 +213,6 @@ async function getPostsFromUserSet(template, req, res) {
|
||||
}
|
||||
const { itemCount, itemData } = result;
|
||||
|
||||
const payload = {};
|
||||
payload[data.type] = itemData[data.type];
|
||||
payload.nextStart = itemData.nextStart;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const nconf = require('nconf');
|
||||
const _ = require('lodash');
|
||||
|
||||
const db = require('../../database');
|
||||
@@ -10,24 +9,13 @@ const posts = require('../../posts');
|
||||
const categories = require('../../categories');
|
||||
const plugins = require('../../plugins');
|
||||
const privileges = require('../../privileges');
|
||||
const accountHelpers = require('./helpers');
|
||||
const helpers = require('../helpers');
|
||||
const utils = require('../../utils');
|
||||
|
||||
const profileController = module.exports;
|
||||
|
||||
profileController.get = async function (req, res, next) {
|
||||
const lowercaseSlug = req.params.userslug.toLowerCase();
|
||||
|
||||
if (req.params.userslug !== lowercaseSlug) {
|
||||
if (res.locals.isAPI) {
|
||||
req.params.userslug = lowercaseSlug;
|
||||
} else {
|
||||
return res.redirect(`${nconf.get('relative_path')}/user/${lowercaseSlug}`);
|
||||
}
|
||||
}
|
||||
|
||||
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
|
||||
const { userData } = res.locals;
|
||||
if (!userData) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -6,13 +6,15 @@ const helpers = require('../helpers');
|
||||
const sessionController = module.exports;
|
||||
|
||||
sessionController.get = async function (req, res) {
|
||||
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
|
||||
const payload = res.locals.userData;
|
||||
const { username, userslug } = payload;
|
||||
|
||||
const payload = {
|
||||
sessions: await user.auth.getSessions(res.locals.uid, req.sessionID),
|
||||
title: '[[pages:account/sessions]]',
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{ text: username, url: `/user/${userslug}` }, { text: '[[pages:account/sessions]]' }]),
|
||||
};
|
||||
payload.sessions = await user.auth.getSessions(res.locals.uid, req.sessionID);
|
||||
payload.title = '[[pages:account/sessions]]';
|
||||
payload.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
{ text: username, url: `/user/${userslug}` },
|
||||
{ text: '[[pages:account/sessions]]' },
|
||||
]);
|
||||
|
||||
res.render('account/sessions', payload);
|
||||
};
|
||||
|
||||
@@ -13,13 +13,12 @@ const plugins = require('../../plugins');
|
||||
const notifications = require('../../notifications');
|
||||
const db = require('../../database');
|
||||
const helpers = require('../helpers');
|
||||
const accountHelpers = require('./helpers');
|
||||
const slugify = require('../../slugify');
|
||||
|
||||
const settingsController = module.exports;
|
||||
|
||||
settingsController.get = async function (req, res, next) {
|
||||
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
|
||||
const { userData } = res.locals;
|
||||
if (!userData) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const db = require('../../database');
|
||||
const user = require('../../user');
|
||||
const helpers = require('../helpers');
|
||||
|
||||
const tagsController = module.exports;
|
||||
@@ -10,10 +9,10 @@ tagsController.get = async function (req, res) {
|
||||
if (req.uid !== res.locals.uid) {
|
||||
return helpers.notAllowed(req, res);
|
||||
}
|
||||
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
|
||||
const payload = res.locals.userData;
|
||||
const { username, userslug } = payload;
|
||||
const tagData = await db.getSortedSetRange(`uid:${res.locals.uid}:followed_tags`, 0, -1);
|
||||
|
||||
const payload = {};
|
||||
payload.tags = tagData;
|
||||
payload.title = `[[pages:account/watched-tags, ${username}]]`;
|
||||
payload.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
|
||||
@@ -6,14 +6,14 @@ const nconf = require('nconf');
|
||||
|
||||
const db = require('../../database');
|
||||
const helpers = require('../helpers');
|
||||
const user = require('../../user');
|
||||
const meta = require('../../meta');
|
||||
const pagination = require('../../pagination');
|
||||
|
||||
const uploadsController = module.exports;
|
||||
|
||||
uploadsController.get = async function (req, res) {
|
||||
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
|
||||
const payload = res.locals.userData;
|
||||
const { username, userslug } = payload;
|
||||
const page = Math.max(1, parseInt(req.query.page, 10) || 1);
|
||||
const itemsPerPage = 25;
|
||||
const start = (page - 1) * itemsPerPage;
|
||||
@@ -23,7 +23,6 @@ uploadsController.get = async function (req, res) {
|
||||
db.getSortedSetRevRange(`uid:${res.locals.uid}:uploads`, start, stop),
|
||||
]);
|
||||
|
||||
const payload = {};
|
||||
payload.uploads = uploadNames.map(uploadName => ({
|
||||
name: uploadName,
|
||||
url: path.resolve(nconf.get('upload_url'), uploadName),
|
||||
|
||||
@@ -88,7 +88,6 @@ apiController.loadConfig = async function (req) {
|
||||
thumbs: {
|
||||
size: meta.config.topicThumbSize,
|
||||
},
|
||||
iconBackgrounds: await user.getIconBackgrounds(req.uid),
|
||||
emailPrompt: meta.config.emailPrompt,
|
||||
useragent: req.useragent,
|
||||
fontawesome: {
|
||||
|
||||
@@ -116,7 +116,7 @@ module.exports = function (middleware) {
|
||||
}
|
||||
|
||||
try {
|
||||
await renderMethod(template, { ...res.locals.templateValues, ...options }, fn);
|
||||
await renderMethod(template, options, fn);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ const meta = require('../meta');
|
||||
const helpers = require('./helpers');
|
||||
const user = require('../user');
|
||||
|
||||
const cache = cacheCreate({
|
||||
ttl: meta.config.uploadRateLimitCooldown * 1000,
|
||||
});
|
||||
let cache;
|
||||
|
||||
exports.clearCache = function () {
|
||||
if (cache) {
|
||||
cache.clear();
|
||||
}
|
||||
};
|
||||
|
||||
exports.ratelimit = helpers.try(async (req, res, next) => {
|
||||
@@ -18,7 +18,11 @@ exports.ratelimit = helpers.try(async (req, res, next) => {
|
||||
if (!meta.config.uploadRateLimitThreshold || (uid && await user.isAdminOrGlobalMod(uid))) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!cache) {
|
||||
cache = cacheCreate({
|
||||
ttl: meta.config.uploadRateLimitCooldown * 1000,
|
||||
});
|
||||
}
|
||||
const count = (cache.get(`${req.ip}:uploaded_file_count`) || 0) + req.files.files.length;
|
||||
if (count > meta.config.uploadRateLimitThreshold) {
|
||||
return next(new Error(['[[error:upload-ratelimit-reached]]']));
|
||||
|
||||
@@ -248,7 +248,18 @@ module.exports = function (middleware) {
|
||||
};
|
||||
|
||||
middleware.buildAccountData = async (req, res, next) => {
|
||||
res.locals.templateValues = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
|
||||
// use lowercase slug on api routes, or direct to the user/<lowercaseslug>
|
||||
const lowercaseSlug = req.params.userslug.toLowerCase();
|
||||
if (req.params.userslug !== lowercaseSlug) {
|
||||
if (res.locals.isAPI) {
|
||||
req.params.userslug = lowercaseSlug;
|
||||
} else {
|
||||
const newPath = req.path.replace(new RegExp(`/${req.params.userslug}`), () => `/${lowercaseSlug}`);
|
||||
return res.redirect(`${nconf.get('relative_path')}${newPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
res.locals.userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
|
||||
next();
|
||||
};
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ module.exports = function (User) {
|
||||
await db.sortedSetAdd('users:banned', now, uid);
|
||||
await db.sortedSetAdd(`uid:${uid}:bans:timestamp`, now, banKey);
|
||||
await db.setObject(banKey, banData);
|
||||
await User.setUserField(uid, 'banned:expire', banData.expire);
|
||||
await User.setUserFields(uid, { banned: 1, 'banned:expire': banData.expire });
|
||||
if (until > now) {
|
||||
await db.sortedSetAdd('users:banned:expire', until, uid);
|
||||
} else {
|
||||
@@ -69,7 +69,7 @@ module.exports = function (User) {
|
||||
uids = isArray ? uids : [uids];
|
||||
const userData = await User.getUsersFields(uids, ['email:confirmed']);
|
||||
|
||||
await db.setObject(uids.map(uid => `user:${uid}`), { 'banned:expire': 0 });
|
||||
await db.setObject(uids.map(uid => `user:${uid}`), { banned: 0, 'banned:expire': 0 });
|
||||
const now = Date.now();
|
||||
const unbanDataArray = [];
|
||||
/* eslint-disable no-await-in-loop */
|
||||
@@ -124,16 +124,15 @@ module.exports = function (User) {
|
||||
|
||||
User.bans.unbanIfExpired = async function (uids) {
|
||||
// loading user data will unban if it has expired -barisu
|
||||
const userData = await User.getUsersFields(uids, ['banned:expire']);
|
||||
const userData = await User.getUsersFields(uids, ['banned', 'banned:expire']);
|
||||
return User.bans.calcExpiredFromUserData(userData);
|
||||
};
|
||||
|
||||
User.bans.calcExpiredFromUserData = async function (userData) {
|
||||
User.bans.calcExpiredFromUserData = function (userData) {
|
||||
const isArray = Array.isArray(userData);
|
||||
userData = isArray ? userData : [userData];
|
||||
const banned = await groups.isMembers(userData.map(u => u.uid), groups.BANNED_USERS);
|
||||
userData = userData.map((userData, index) => ({
|
||||
banned: banned[index],
|
||||
userData = userData.map(userData => ({
|
||||
banned: !!(userData && userData.banned),
|
||||
'banned:expire': userData && userData['banned:expire'],
|
||||
banExpired: userData && userData['banned:expire'] <= Date.now() && userData['banned:expire'] !== 0,
|
||||
}));
|
||||
|
||||
@@ -45,6 +45,8 @@ module.exports = function (User) {
|
||||
'email:confirmed': 0,
|
||||
};
|
||||
|
||||
let iconBackgrounds;
|
||||
|
||||
User.getUsersFields = async function (uids, fields) {
|
||||
if (!Array.isArray(uids) || !uids.length) {
|
||||
return [];
|
||||
@@ -201,8 +203,12 @@ module.exports = function (User) {
|
||||
['showfullname']
|
||||
));
|
||||
}
|
||||
if (!iconBackgrounds) {
|
||||
iconBackgrounds = await User.getIconBackgrounds();
|
||||
}
|
||||
|
||||
await Promise.all(users.map(async (user) => {
|
||||
const unbanUids = [];
|
||||
users.forEach((user) => {
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
@@ -218,7 +224,7 @@ module.exports = function (User) {
|
||||
user.email = validator.escape(user.email ? user.email.toString() : '');
|
||||
}
|
||||
|
||||
if (!parseInt(user.uid, 10) && !activitypub.helpers.isUri(user.uid)) {
|
||||
if (!user.uid && !activitypub.helpers.isUri(user.uid)) {
|
||||
for (const [key, value] of Object.entries(User.guestData)) {
|
||||
user[key] = value;
|
||||
}
|
||||
@@ -248,15 +254,12 @@ module.exports = function (User) {
|
||||
}
|
||||
|
||||
// User Icons
|
||||
if (requestedFields.includes('picture') && user.username && parseInt(user.uid, 10) !== 0 && !meta.config.defaultAvatar) {
|
||||
const iconBackgrounds = await User.getIconBackgrounds(user.uid);
|
||||
let bgColor = await User.getUserField(user.uid, 'icon:bgColor');
|
||||
if (!iconBackgrounds.includes(bgColor)) {
|
||||
bgColor = Array.prototype.reduce.call(user.username, (cur, next) => cur + next.charCodeAt(), 0);
|
||||
bgColor = iconBackgrounds[bgColor % iconBackgrounds.length];
|
||||
if (requestedFields.includes('picture') && user.username && user.uid !== 0 && !meta.config.defaultAvatar) {
|
||||
if (!iconBackgrounds.includes(user['icon:bgColor'])) {
|
||||
const nameAsIndex = Array.from(user.username).reduce((cur, next) => cur + next.charCodeAt(), 0);
|
||||
user['icon:bgColor'] = iconBackgrounds[nameAsIndex % iconBackgrounds.length];
|
||||
}
|
||||
user['icon:text'] = (user.username[0] || '').toUpperCase();
|
||||
user['icon:bgColor'] = bgColor;
|
||||
}
|
||||
|
||||
if (user.hasOwnProperty('joindate')) {
|
||||
@@ -267,22 +270,25 @@ module.exports = function (User) {
|
||||
user.lastonlineISO = utils.toISOString(user.lastonline) || user.joindateISO;
|
||||
}
|
||||
|
||||
if (user.hasOwnProperty('mutedUntil')) {
|
||||
user.muted = user.mutedUntil > Date.now();
|
||||
}
|
||||
|
||||
if (user.hasOwnProperty('banned') || user.hasOwnProperty('banned:expire')) {
|
||||
const result = await User.bans.calcExpiredFromUserData(user);
|
||||
const result = User.bans.calcExpiredFromUserData(user);
|
||||
user.banned = result.banned;
|
||||
const unban = result.banned && result.banExpired;
|
||||
user.banned_until = unban ? 0 : user['banned:expire'];
|
||||
user.banned_until_readable = user.banned_until && !unban ? utils.toISOString(user.banned_until) : 'Not Banned';
|
||||
if (unban) {
|
||||
await User.bans.unban(user.uid, '[[user:info.ban-expired]]');
|
||||
unbanUids.push(user.uid);
|
||||
user.banned = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (user.hasOwnProperty('mutedUntil')) {
|
||||
user.muted = user.mutedUntil > Date.now();
|
||||
});
|
||||
if (unbanUids.length) {
|
||||
await User.bans.unban(unbanUids, '[[user:info.ban-expired]]');
|
||||
}
|
||||
}));
|
||||
|
||||
return await plugins.hooks.fire('filter:users.get', users);
|
||||
}
|
||||
@@ -332,14 +338,20 @@ module.exports = function (User) {
|
||||
}
|
||||
}
|
||||
|
||||
User.getIconBackgrounds = async (uid = 0) => {
|
||||
let iconBackgrounds = [
|
||||
|
||||
User.getIconBackgrounds = async () => {
|
||||
if (iconBackgrounds) {
|
||||
return iconBackgrounds;
|
||||
}
|
||||
|
||||
const _iconBackgrounds = [
|
||||
'#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3',
|
||||
'#009688', '#1b5e20', '#33691e', '#827717', '#e65100', '#ff5722',
|
||||
'#795548', '#607d8b',
|
||||
];
|
||||
|
||||
({ iconBackgrounds } = await plugins.hooks.fire('filter:user.iconBackgrounds', { uid, iconBackgrounds }));
|
||||
const data = await plugins.hooks.fire('filter:user.iconBackgrounds', { iconBackgrounds: _iconBackgrounds });
|
||||
iconBackgrounds = data.iconBackgrounds;
|
||||
return iconBackgrounds;
|
||||
};
|
||||
|
||||
|
||||
@@ -607,7 +607,7 @@ describe('User', () => {
|
||||
|
||||
it('should return an icon text and valid background if username and picture is explicitly requested', async () => {
|
||||
const payload = await User.getUserFields(testUid, ['username', 'picture']);
|
||||
const validBackgrounds = await User.getIconBackgrounds(testUid);
|
||||
const validBackgrounds = await User.getIconBackgrounds();
|
||||
assert.strictEqual(payload['icon:text'], userData.username.slice(0, 1).toUpperCase());
|
||||
assert(payload['icon:bgColor']);
|
||||
assert(validBackgrounds.includes(payload['icon:bgColor']));
|
||||
@@ -616,7 +616,7 @@ describe('User', () => {
|
||||
it('should return a valid background, even if an invalid background colour is set', async () => {
|
||||
await User.setUserField(testUid, 'icon:bgColor', 'teal');
|
||||
const payload = await User.getUserFields(testUid, ['username', 'picture']);
|
||||
const validBackgrounds = await User.getIconBackgrounds(testUid);
|
||||
const validBackgrounds = await User.getIconBackgrounds();
|
||||
|
||||
assert(payload['icon:bgColor']);
|
||||
assert(validBackgrounds.includes(payload['icon:bgColor']));
|
||||
|
||||
Reference in New Issue
Block a user