nodebb-plugin-admin-chats 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client.js ADDED
@@ -0,0 +1,59 @@
1
+ $(document).ready(function() {
2
+
3
+ function isEnglishSystem() {
4
+ return $('html').attr('lang') && $('html').attr('lang').startsWith('en');
5
+ }
6
+
7
+ function replaceAdminEmptyStateText() {
8
+ if (!app.user.isAdmin) return;
9
+
10
+ $('span.text-muted.text-sm').each(function() {
11
+ const currentText = $(this).text().trim();
12
+
13
+ if (currentText.includes("אין לכם צ'אטים פעילים") || currentText === "אין לכם צ'אטים פעילים.") {
14
+ $(this).text("אנא בחר צ'אט מסרגל הצד.");
15
+ $(this).removeClass('text-muted');
16
+ }
17
+
18
+ if (currentText.includes("You have no active chats") || currentText === "You have no active chats.") {
19
+ $(this).text("Please select a chat from the sidebar.");
20
+ $(this).removeClass('text-muted');
21
+ }
22
+ });
23
+ }
24
+
25
+ $(window).on('action:ajaxify.end', function(ev, data) {
26
+
27
+ if (app.user.isAdmin && (data.tpl_url === 'account/profile' || ajaxify.data.template.name === 'account/profile')) {
28
+ const userSlug = ajaxify.data.userslug || (ajaxify.data.user && ajaxify.data.user.userslug);
29
+ if (userSlug) {
30
+ const buttonText = isEnglishSystem() ? "View Chats" : "צפה בצ'אטים";
31
+
32
+ const btnHtml = `
33
+ <li role="presentation">
34
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" href="/user/${userSlug}/chats" role="menuitem">
35
+ <i class="far fa-fw fa-comments"></i>
36
+ <span>${buttonText}</span>
37
+ </a>
38
+ </li>
39
+ <li role="presentation" class="dropdown-divider"></li>
40
+ `;
41
+ const menu = $('.account-sub-links');
42
+ if (menu.length) {
43
+ menu.find(`a[href*="/user/${userSlug}/chats"]`).parent().remove();
44
+ menu.prepend(btnHtml);
45
+ }
46
+ }
47
+ }
48
+
49
+ if (data.url.match(/^user\/.+\/chats/) || data.url === 'chats') {
50
+ replaceAdminEmptyStateText();
51
+ setTimeout(replaceAdminEmptyStateText, 500);
52
+ }
53
+ });
54
+
55
+ $(window).on('action:chat.loaded', replaceAdminEmptyStateText);
56
+ $(window).on('action:chat.closed', function() {
57
+ setTimeout(replaceAdminEmptyStateText, 200);
58
+ });
59
+ });
package/library.js ADDED
@@ -0,0 +1,160 @@
1
+ 'use strict';
2
+
3
+ const User = require.main.require('./src/user');
4
+ const Messaging = require.main.require('./src/messaging');
5
+ const db = require.main.require('./src/database');
6
+ const _ = require('lodash');
7
+
8
+ const plugin = {};
9
+
10
+ plugin.init = async function (params) {
11
+
12
+ overrideMessagingFunctions();
13
+ };
14
+
15
+
16
+ plugin.addProfileLink = async function (data) {
17
+ try {
18
+ const userSlug = data.user ? data.user.userslug : (data.userData ? data.userData.userslug : null);
19
+
20
+ if (userSlug) {
21
+ data.links.push({
22
+ id: 'admin-view-chats',
23
+ route: 'user/' + userSlug + '/chats',
24
+ icon: 'fa-comments',
25
+ name: 'צפה בצ\'אטים',
26
+ visibility: {
27
+ self: false,
28
+ other: true,
29
+ moderator: false,
30
+ globalMod: false,
31
+ admin: true,
32
+ }
33
+ });
34
+ }
35
+ } catch (e) {
36
+ console.error('[Super Admin Chats] Error adding profile link:', e);
37
+ }
38
+ return data;
39
+ };
40
+
41
+ plugin.isRoomOwner = async function (payload) {
42
+ const isAdmin = await User.isAdministrator(payload.uid);
43
+ if (isAdmin) {
44
+ payload.isOwner = true;
45
+ }
46
+ return payload;
47
+ };
48
+
49
+ plugin.isUserInRoom = async function (payload) {
50
+ const isAdmin = await User.isAdministrator(payload.uid);
51
+ if (isAdmin) {
52
+ payload.inRoom = true;
53
+ }
54
+ return payload;
55
+ };
56
+
57
+ plugin.canReply = async function (payload) {
58
+ const isAdmin = await User.isAdministrator(payload.uid);
59
+ if (isAdmin) {
60
+ payload.canReply = true;
61
+ }
62
+ return payload;
63
+ };
64
+
65
+ plugin.canGetMessages = async function (payload) {
66
+ const isAdmin = await User.isAdministrator(payload.callerUid);
67
+ if (isAdmin) {
68
+ payload.canGet = true;
69
+ }
70
+ return payload;
71
+ };
72
+
73
+ plugin.canGetRecentChats = async function (payload) {
74
+ const isAdmin = await User.isAdministrator(payload.callerUid);
75
+ if (isAdmin) {
76
+ payload.canGet = true;
77
+ }
78
+ return payload;
79
+ };
80
+
81
+ plugin.canGetPublicChats = async function (payload) {
82
+ const isAdmin = await User.isAdministrator(payload.callerUid);
83
+ if (isAdmin) {
84
+ payload.canGet = true;
85
+ }
86
+ return payload;
87
+ };
88
+
89
+ plugin.onLoadRoom = async function (payload) {
90
+ const { uid, room } = payload;
91
+ const isAdmin = await User.isAdministrator(uid);
92
+
93
+ if (!isAdmin || !room) return payload;
94
+
95
+ const isOfficialMember = await db.isSortedSetMember(`chat:room:${room.roomId}:uids`, uid);
96
+
97
+ if (!isOfficialMember) {
98
+ await db.sortedSetRemove(`chat:room:${room.roomId}:uids:online`, uid);
99
+
100
+ if (Array.isArray(room.users)) {
101
+ room.users = room.users.filter(user => user && parseInt(user.uid, 10) !== parseInt(uid, 10));
102
+ }
103
+
104
+ if (room.userCount > 0) {
105
+ room.userCount -= 1;
106
+ }
107
+ room.groupChat = room.userCount > 2;
108
+
109
+ const allMids = await db.getSortedSetRevRange(`chat:room:${room.roomId}:mids`, 0, 49);
110
+
111
+ if (allMids.length > 0) {
112
+ const messages = await Messaging.getMessagesData(allMids, uid, room.roomId, false);
113
+ const messageCount = await db.getObjectField(`chat:room:${room.roomId}`, 'messageCount');
114
+ const count = parseInt(messageCount, 10) || 0;
115
+
116
+ messages.forEach((msg, index) => {
117
+ msg.index = count - index - 1;
118
+ });
119
+
120
+ room.messages = messages.reverse();
121
+ }
122
+
123
+ room.isAdmin = true;
124
+ room.isOwner = true;
125
+ } else {
126
+ room.isAdmin = true;
127
+ }
128
+
129
+ return payload;
130
+ };
131
+
132
+ function overrideMessagingFunctions() {
133
+
134
+ const originalCanEdit = Messaging.canEdit;
135
+ const originalCanDelete = Messaging.canDelete;
136
+ const originalCanViewMessage = Messaging.canViewMessage;
137
+
138
+ Messaging.canEdit = async function (messageId, uid) {
139
+ if (await User.isAdministrator(uid)) {
140
+ return true;
141
+ }
142
+ return await originalCanEdit(messageId, uid);
143
+ };
144
+
145
+ Messaging.canDelete = async function (messageId, uid) {
146
+ if (await User.isAdministrator(uid)) {
147
+ return true;
148
+ }
149
+ return await originalCanDelete(messageId, uid);
150
+ };
151
+
152
+ Messaging.canViewMessage = async function (mids, roomId, uid) {
153
+ if (await User.isAdministrator(uid)) {
154
+ return Array.isArray(mids) ? mids.map(() => true) : true;
155
+ }
156
+ return await originalCanViewMessage(mids, roomId, uid);
157
+ };
158
+ }
159
+
160
+ module.exports = plugin;
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "nodebb-plugin-admin-chats",
3
+ "version": "1.0.0",
4
+ "description": "A plugin that allows the administrator to view and manage user chats.",
5
+ "main": "library.js",
6
+ "dependencies": {
7
+ "lodash": "^4.17.0"
8
+ },
9
+ "nbbpm": {
10
+ "compatibility": "^3.0.0 || ^4.0.0"
11
+ }
12
+ }
package/plugin.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "nodebb-plugin-admin-chats",
3
+ "name": "Super Admin Chat Control",
4
+ "description": "A plugin that allows the administrator to view and manage user chats",
5
+ "url": "https://github.com/palmoni5/nodebb-plugin-admin-chats",
6
+ "library": "./library.js",
7
+ "scripts": [ "client.js" ],
8
+ "hooks": [
9
+ { "hook": "filter:user.accountMenu", "method": "addProfileLink" },
10
+ { "hook": "filter:messaging.isRoomOwner", "method": "isRoomOwner" },
11
+ { "hook": "filter:messaging.isUserInRoom", "method": "isUserInRoom" },
12
+ { "hook": "filter:messaging.canReply", "method": "canReply" },
13
+ { "hook": "filter:messaging.canGetMessages", "method": "canGetMessages" },
14
+ { "hook": "filter:messaging.canGetRecentChats", "method": "canGetRecentChats" },
15
+ { "hook": "filter:messaging.canGetPublicChats", "method": "canGetPublicChats" },
16
+ { "hook": "filter:messaging.loadRoom", "method": "onLoadRoom" },
17
+ { "hook": "static:app.load", "method": "init" }
18
+ ]
19
+ }