From 56e74e08771c9050ffcb9993a271759e35ca9c01 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Sat, 12 Jun 2021 01:16:57 +0200 Subject: [PATCH] Initialize prosody-list-rooms button. --- assets/style.css | 6 ++- client/@types/peertube.d.ts | 1 + client/admin-plugin-client-plugin.ts | 56 +++++++++++++++++++++++++++- server/lib/routers/settings.ts | 33 ++++++++++++++++ server/lib/settings.ts | 7 ++++ shared/lib/types.ts | 20 +++++++++- 6 files changed, 119 insertions(+), 4 deletions(-) diff --git a/assets/style.css b/assets/style.css index e5daefed..be88360a 100644 --- a/assets/style.css +++ b/assets/style.css @@ -53,4 +53,8 @@ .peertube-plugin-livechat-warning { color: orange; -} \ No newline at end of file +} + +.peertube-plugin-livechat-error { + color: red; +} diff --git a/client/@types/peertube.d.ts b/client/@types/peertube.d.ts index 3121a03d..0d0772fc 100644 --- a/client/@types/peertube.d.ts +++ b/client/@types/peertube.d.ts @@ -11,6 +11,7 @@ interface RegisterClientHelpers { // NB: getBaseRouterRoute will come with Peertube > 3.2.1 (3.3.0?) getBaseRouterRoute?: () => string isLoggedIn: () => boolean + getAuthHeader: () => { 'Authorization': string } | undefined getSettings: () => Promise<{ [ name: string ]: string }> notifier: { info: (text: string, title?: string, timeout?: number) => void diff --git a/client/admin-plugin-client-plugin.ts b/client/admin-plugin-client-plugin.ts index 163b5c0d..5391cc45 100644 --- a/client/admin-plugin-client-plugin.ts +++ b/client/admin-plugin-client-plugin.ts @@ -1,4 +1,4 @@ -import type { ChatType } from 'shared/lib/types' +import type { ChatType, ProsodyListRoomsResult } from 'shared/lib/types' interface ActionPluginSettingsParams { npmName: string @@ -31,6 +31,59 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re diagButton.setAttribute('href', getBaseRoute() + '/settings/diagnostic') diagButton.setAttribute('target', '_blank') }) + console.log('[peertube-plugin-livechat] Initializing prosody-list-rooms button') + const listRoomsButtons: NodeListOf = + document.querySelectorAll('.peertube-plugin-livechat-prosody-list-rooms') + listRoomsButtons.forEach(listRoomsButton => { + if (listRoomsButton.classList.contains('btn')) { return } + listRoomsButton.classList.add('btn') + listRoomsButton.classList.add('action-button') + listRoomsButton.classList.add('orange-button') + listRoomsButton.onclick = async (): Promise => { + console.log('[peertube-plugin-livechat] Opening the room list...') + // TODO: use showModal (seems buggy with Peertube 3.2.1) + + try { + document.querySelectorAll('.peertube-plugin-livechat-prosody-list-rooms-content') + .forEach(dom => dom.remove()) + const container = document.createElement('div') + container.classList.add('peertube-plugin-livechat-prosody-list-rooms-content') + container.textContent = '...' + listRoomsButton.after(container) + + const response = await fetch(getBaseRoute() + '/settings/prosody-list-rooms', { + method: 'GET', + headers: peertubeHelpers.getAuthHeader() + }) + if (!response.ok) { + throw new Error('Response is not ok') + } + const json: ProsodyListRoomsResult = await response.json() + if (!json.ok) { + container.textContent = json.error + container.classList.add('peertube-plugin-livechat-error') + } else { + container.textContent = '' + const table = document.createElement('table') + container.append(table) + json.rooms.forEach(room => { + const lineEl = document.createElement('tr') + const nameEl = document.createElement('td') + const aEl = document.createElement('a') + aEl.textContent = room.name + aEl.href = room.href + aEl.target = '_blank' + nameEl.append(aEl) + lineEl.append(nameEl) + table.append(lineEl) + }) + } + } catch (error) { + console.error(error) + peertubeHelpers.notifier.error('Room list failed') + } + } + }) } }) registerSettingsScript({ @@ -41,6 +94,7 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re return options.formValues['chat-type'] !== ('disabled' as ChatType) case 'prosody-port': case 'chat-type-help-builtin-prosody': + case 'prosody-list-rooms': return options.formValues['chat-type'] !== ('builtin-prosody' as ChatType) case 'chat-server': case 'chat-room': diff --git a/server/lib/routers/settings.ts b/server/lib/routers/settings.ts index a2510c2c..88930655 100644 --- a/server/lib/routers/settings.ts +++ b/server/lib/routers/settings.ts @@ -1,4 +1,5 @@ import type { Router, Request, Response, NextFunction } from 'express' +import type { ChatType, ProsodyListRoomsResult } from '../../../shared/lib/types' import { diag } from '../diagnostic' import { getBaseStaticRoute, isUserAdmin } from '../helpers' import { asyncMiddleware } from '../middlewares/async' @@ -39,6 +40,38 @@ async function initSettingsRouter (options: RegisterServerOptions): Promise { + if (!res.locals.authenticated) { + res.sendStatus(403) + return + } + if (!await isUserAdmin(options, res)) { + res.sendStatus(403) + return + } + + const chatType: ChatType = await options.settingsManager.getSetting('chat-type') as ChatType + if (chatType !== 'builtin-prosody') { + const message = 'Please save the settings first.' // TODO: translate? + res.status(200) + const r: ProsodyListRoomsResult = { + ok: false, + error: message + } + res.json(r) + return + } + + res.status(200) + const r: ProsodyListRoomsResult = { + ok: true, + rooms: [] // TODO: get room list from Prosody + } + res.json(r) + } + )) + return router } diff --git a/server/lib/settings.ts b/server/lib/settings.ts index d4ed53fc..29ba67f1 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -91,6 +91,13 @@ Please read the private: true }) + registerSetting({ + name: 'prosody-list-rooms', + label: 'List existing rooms', + type: 'html', + descriptionHTML: 'List rooms', + private: true + }) registerSetting({ name: 'prosody-port', label: 'Prosody port', diff --git a/shared/lib/types.ts b/shared/lib/types.ts index f9892324..8fefdd23 100644 --- a/shared/lib/types.ts +++ b/shared/lib/types.ts @@ -1,5 +1,21 @@ type ChatType = 'disabled' | 'builtin-prosody' | 'builtin-converse' | 'external-uri' -export { - ChatType +interface ProsodyListRoomsResultError { + ok: false + error: string +} + +interface ProsodyListRoomsResultSuccess { + ok: true + rooms: Array<{ + name: string + href: string + }> +} + +type ProsodyListRoomsResult = ProsodyListRoomsResultError | ProsodyListRoomsResultSuccess + +export { + ChatType, + ProsodyListRoomsResult }