From acc71d4cae476749e1f4d95370fb8513d939fde3 Mon Sep 17 00:00:00 2001 From: Aevann Date: Fri, 20 Jan 2023 06:10:25 +0200 Subject: [PATCH] add /admin/chat and dont store profile_url in chat dict --- files/assets/js/chat_done.js | 17 ++--- files/routes/chat.py | 99 +++++++++++++++++------------ files/routes/wrappers.py | 2 + files/templates/chat.html | 1 - files/templates/util/html_head.html | 2 +- nginx.conf | 4 ++ 6 files changed, 69 insertions(+), 56 deletions(-) diff --git a/files/assets/js/chat_done.js b/files/assets/js/chat_done.js index f7491fac1..d04eebcfc 100644 --- a/files/assets/js/chat_done.js +++ b/files/assets/js/chat_done.js @@ -32931,7 +32931,6 @@ themeColor, siteName, nameColor, - avatar, hat }, setContext @@ -32943,7 +32942,6 @@ themeColor: "#ff66ac", siteName: "", nameColor: "", - avatar: "", hat: "" }); (0, import_react13.useEffect)(() => { @@ -32956,7 +32954,6 @@ themeColor: root2.dataset.themecolor, siteName: root2.dataset.sitename, nameColor: root2.dataset.namecolor, - avatar: root2.dataset.avatar, hat: root2.dataset.hat }); }, []); @@ -32968,7 +32965,6 @@ themeColor, siteName, nameColor, - avatar, hat }; } @@ -33014,7 +33010,7 @@ var DIRECT_MESSAGE_ID = "DIRECT_MESSAGE"; var OPTIMISTIC_MESSAGE_ID = "OPTIMISTIC"; function ChatProvider({ children }) { - const { username, id, siteName, hat, avatar, nameColor } = useRootContext(); + const { username, id, siteName, hat, nameColor } = useRootContext(); const socket = (0, import_react15.useRef)(null); const [online, setOnline] = (0, import_react15.useState)([]); const [typing, setTyping] = (0, import_react15.useState)([]); @@ -33054,7 +33050,6 @@ id: DIRECT_MESSAGE_ID, username, user_id: id, - avatar, hat, namecolor: nameColor, text: directMessage, @@ -33070,7 +33065,6 @@ id: OPTIMISTIC_MESSAGE_ID, username, user_id: id, - avatar, hat, namecolor: nameColor, text: draft, @@ -33485,14 +33479,14 @@ // src/features/chat/Username.tsx var import_react20 = __toESM(require_react()); - function Username({ avatar, color, name, hat = "" }) { + function Username({ id, color, name, hat = "" }) { return /* @__PURE__ */ import_react20.default.createElement("div", { className: "Username" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "profile-pic-20-wrapper" }, /* @__PURE__ */ import_react20.default.createElement("img", { alt: name, - src: avatar, + src: `/pp/${id}`, className: "pp20" }), hat && /* @__PURE__ */ import_react20.default.createElement("img", { className: "avatar-hat profile-pic-20-hat hat", @@ -33559,7 +33553,6 @@ const { id, user_id, - avatar, namecolor, username, hat, @@ -33676,10 +33669,10 @@ }, /* @__PURE__ */ import_react22.default.createElement("i", null, "X"), " Close")), showUser && /* @__PURE__ */ import_react22.default.createElement("div", { className: "ChatMessage-top" }, /* @__PURE__ */ import_react22.default.createElement(Username, { - avatar, + id: user_id, name: username, color: namecolor, - hat + hat, }), /* @__PURE__ */ import_react22.default.createElement("div", { className: "ChatMessage-timestamp" }, timestamp)), quotes && quotedMessage && /* @__PURE__ */ import_react22.default.createElement("div", { diff --git a/files/routes/chat.py b/files/routes/chat.py index 666e192ae..4649971a1 100644 --- a/files/routes/chat.py +++ b/files/routes/chat.py @@ -2,7 +2,7 @@ import atexit import time import uuid -from flask_socketio import SocketIO, emit +from flask_socketio import SocketIO, emit, join_room, leave_room from files.helpers.actions import * from files.helpers.alerts import * @@ -28,12 +28,20 @@ else: async_mode='gevent', ) -typing = [] -online = [] +typing = { + f'{SITE_FULL}/chat': [], + f'{SITE_FULL}/admin/chat': [] +} +online = [] cache.set(CHAT_ONLINE_CACHE_KEY, len(online), timeout=0) -muted = cache.get(f'{SITE}_muted') or {} -messages = cache.get(f'{SITE}_chat') or [] -total = cache.get(f'{SITE}_total') or 0 +muted = cache.get(f'muted') or { + f'{SITE_FULL}/chat': {}, + f'{SITE_FULL}/admin/chat': {} +} +messages = cache.get(f'messages') or { + f'{SITE_FULL}/chat': [], + f'{SITE_FULL}/admin/chat': [] +} socket_ids_to_user_ids = {} user_ids_to_socket_ids = {} @@ -42,8 +50,12 @@ user_ids_to_socket_ids = {} def chat(v): if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM: abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat.") - return render_template("chat.html", v=v, messages=messages) + return render_template("chat.html", v=v) +@app.get("/admin/chat") +@admin_level_required(2) +def admin_chat(v): + return render_template("chat.html", v=v) @socketio.on('speak') @limiter.limit("3/second;10/minute") @@ -56,11 +68,11 @@ def speak(data, v): return '', 403 vname = v.username.lower() - if vname in muted and not v.admin_level >= PERMS['CHAT_BYPASS_MUTE']: - if time.time() < muted[vname]: return '', 403 - else: del muted[vname] + if vname in muted[request.referrer] and not v.admin_level >= PERMS['CHAT_BYPASS_MUTE']: + if time.time() < muted[request.referrer][vname]: return '', 403 + else: del muted[request.referrer][vname] - global messages, total + global messages text = sanitize_raw_body(data['message'], False)[:CHAT_LENGTH_LIMIT] if not text: return '', 400 @@ -71,7 +83,6 @@ def speak(data, v): data = { "id": str(uuid.uuid4()), "quotes": quotes, - "avatar": v.profile_url, "hat": v.hat_active(v)[0], "user_id": v.id, "dm": bool(recipient and recipient != ""), @@ -91,50 +102,50 @@ def speak(data, v): recipient_sid = user_ids_to_socket_ids[recipient] emit('speak', data, broadcast=False, to=recipient_sid) else: - emit('speak', data, broadcast=True) - messages.append(data) - messages = messages[-500:] - - total += 1 + emit('speak', data, room=request.referrer, broadcast=True) + messages[request.referrer].append(data) + messages[request.referrer] = messages[request.referrer][-500:] if v.admin_level >= PERMS['USER_BAN']: text = text.lower() for i in mute_regex.finditer(text): username = i.group(1).lower() duration = int(int(i.group(2)) * 60 + time.time()) - muted[username] = duration + muted[request.referrer][username] = duration typing = [] - # if SITE == 'rdrama.net': - # title = f'New chat message from @{v.username}' - # notifbody = text - # url = f'{SITE_FULL}/chat' + if request.referrer == f'{SITE_FULL}/admin/chat': + title = f'New message in admin chat from @{v.username}' + notifbody = text + url = f'{SITE_FULL}/admin/chat' - # admin_ids = [x[0] for x in g.db.query(User.id).filter( - # User.id != v.id, - # User.admin_level >= PERMS['CHAT'], - # ).all()] + admin_ids = [x[0] for x in g.db.query(User.id).filter( + User.id != v.id, + User.admin_level >= PERMS['CHAT'], + ).all()] - # push_notif(admin_ids, title, notifbody, url) + push_notif(admin_ids, title, notifbody, url) return '', 204 @socketio.on('connect') @admin_level_required(PERMS['CHAT']) def connect(v): + join_room(request.referrer) + if v.username not in online: online.append(v.username) - emit("online", online, broadcast=True) + emit("online", online, room=request.referrer, broadcast=True) cache.set(CHAT_ONLINE_CACHE_KEY, len(online), timeout=0) if not socket_ids_to_user_ids.get(request.sid): socket_ids_to_user_ids[request.sid] = v.id user_ids_to_socket_ids[v.id] = request.sid - emit('online', online) - emit('catchup', messages) - emit('typing', typing) + emit('online', online, room=request.referrer) + emit('catchup', messages[request.referrer], room=request.referrer) + emit('typing', typing[request.referrer], room=request.referrer) return '', 204 @socketio.on('disconnect') @@ -142,26 +153,31 @@ def connect(v): def disconnect(v): if v.username in online: online.remove(v.username) - emit("online", online, broadcast=True) + emit("online", online, room=request.referrer, broadcast=True) cache.set(CHAT_ONLINE_CACHE_KEY, len(online), timeout=0) - if v.username in typing: typing.remove(v.username) + if v.username in typing[request.referrer]: + typing[request.referrer].remove(v.username) if socket_ids_to_user_ids.get(request.sid): del socket_ids_to_user_ids[request.sid] del user_ids_to_socket_ids[v.id] - emit('typing', typing, broadcast=True) + emit('typing', typing[request.referrer], room=request.referrer, broadcast=True) + + leave_room(request.referrer) return '', 204 @socketio.on('typing') @admin_level_required(PERMS['CHAT']) def typing_indicator(data, v): - if data and v.username not in typing: typing.append(v.username) - elif not data and v.username in typing: typing.remove(v.username) + if data and v.username not in typing[request.referrer]: + typing[request.referrer].append(v.username) + elif not data and v.username in typing[request.referrer]: + typing[request.referrer].remove(v.username) - emit('typing', typing, broadcast=True) + emit('typing', typing[request.referrer], room=request.referrer, broadcast=True) return '', 204 @@ -171,15 +187,14 @@ def delete(text, v): for message in messages: if message['text'] == text: - messages.remove(message) + messages[request.referrer].remove(message) - emit('delete', text, broadcast=True) + emit('delete', text, room=request.referrer, broadcast=True) return '', 204 def close_running_threads(): - cache.set(f'{SITE}_chat', messages) - cache.set(f'{SITE}_total', total) - cache.set(f'{SITE}_muted', muted) + cache.set(f'messages', messages) + cache.set(f'muted', muted) atexit.register(close_running_threads) diff --git a/files/routes/wrappers.py b/files/routes/wrappers.py index 12d3fb90f..2ea9ea3cb 100644 --- a/files/routes/wrappers.py +++ b/files/routes/wrappers.py @@ -116,6 +116,8 @@ def admin_level_required(x): if v.admin_level < x: abort(403) if x and SITE != 'devrama.net' and not IS_LOCALHOST and not v.mfa_secret: abort(403, "You need to enable 2FA to use admin features!") + if request.referrer == f'{SITE_FULL}/admin/chat' and v.admin_level < PERMS['CHAT']: + abort(403) return make_response(f(*args, v=v, **kwargs)) wrapper.__name__ = f.__name__ diff --git a/files/templates/chat.html b/files/templates/chat.html index d18cb1874..7f52583c2 100644 --- a/files/templates/chat.html +++ b/files/templates/chat.html @@ -14,7 +14,6 @@ data-sitename="{{SITE_NAME}}" data-themecolor="{{v.themecolor}}" data-namecolor="{{v.namecolor}}" - data-avatar="{{v.profile_url}}" data-hat="{{v.hat_active(v)[0]}}"> diff --git a/files/templates/util/html_head.html b/files/templates/util/html_head.html index ee6bd31f0..7eeca501e 100644 --- a/files/templates/util/html_head.html +++ b/files/templates/util/html_head.html @@ -134,7 +134,7 @@ {% endif %} {% endif %} - {% if request.path == '/chat' %} + {% if request.path.endswith('/chat') %} {% endif %} {% endmacro %} diff --git a/nginx.conf b/nginx.conf index ee080e0ff..c474bb32c 100644 --- a/nginx.conf +++ b/nginx.conf @@ -23,6 +23,10 @@ server { proxy_pass http://localhost:5001/chat; include includes/headers; } + location /admin/chat { + proxy_pass http://localhost:5001/admin/chat; + include includes/headers; + } location =/offline.html { alias /rDrama/files/assets/offline.html; include includes/headers;