Merge branch 'release/3.2.0' into main
This commit is contained in:
commit
537897e1ed
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## v3.2.0
|
||||
|
||||
### Features
|
||||
|
||||
* Builtin Prosody: list existing rooms in the settings page
|
||||
* Builtin Prosody: new settings to enable local C2S. For example, can be used with Matterbridge (thanks https://github.com/tytan652)
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix broken API diagnostic.
|
||||
|
||||
## v3.1.0
|
||||
|
||||
### Features
|
||||
|
@ -24,6 +24,7 @@ If you have any question, or if you want to talk about this plugin, you can join
|
||||
## Settings
|
||||
|
||||
For the chat mode, and related settings, please refer to the corresponding documentation:
|
||||
|
||||
* [Prosody server controlled by Peertube (recommended)](documentation/prosody.md). **This is the recommanded setup**.
|
||||
* [Connect to an existing XMPP server with ConverseJS](documentation/conversejs.md)
|
||||
* [Use an external web chat tool](documentation/external.md)
|
||||
|
@ -29,7 +29,7 @@ This roadmap is given as an indication. It will be updated as we go along accord
|
||||
[x] | Documentation | Rewrite documentation for more clarity. | v3.0.0
|
||||
[ ] | Documentation | Add screenshots.
|
||||
[ ] | Documentation | User documentation.
|
||||
[ ] | Builtin Prosody | Room administration: add a button in the plugin settings to open a modal with existing rooms list.
|
||||
[.] | Builtin Prosody | Room administration: add a button in the plugin settings to open a modal with existing rooms list. TODO: use a modal. | v3.2.0
|
||||
[ ] | Builtin Prosody | Check with yunohost how to integrate.
|
||||
[ ] | Settings | Translate settings page.
|
||||
[ ] | ConverseJS | UI: make custom templates, for a better UI/UX. Autoshow muc participants depending on the chat window width.
|
||||
|
@ -53,4 +53,34 @@
|
||||
|
||||
.peertube-plugin-livechat-warning {
|
||||
color: orange;
|
||||
}
|
||||
}
|
||||
|
||||
.peertube-plugin-livechat-error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
table.peertube-plugin-livechat-prosody-list-rooms {
|
||||
border: 1px solid black;
|
||||
margin: 5px 0px;
|
||||
}
|
||||
|
||||
table.peertube-plugin-livechat-prosody-list-rooms tr:nth-child(odd) {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
table.peertube-plugin-livechat-prosody-list-rooms tr:nth-child(even) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
table.peertube-plugin-livechat-prosody-list-rooms th {
|
||||
background-color: var(--mainHoverColor);
|
||||
border: 1px solid black;
|
||||
color: var(--mainBackgroundColor);
|
||||
padding: 4px 5px;
|
||||
}
|
||||
|
||||
table.peertube-plugin-livechat-prosody-list-rooms td {
|
||||
border: 1px solid #555;
|
||||
color: black;
|
||||
padding: 4px 5px;
|
||||
}
|
||||
|
2
client/@types/peertube.d.ts
vendored
2
client/@types/peertube.d.ts
vendored
@ -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
|
||||
@ -63,6 +64,7 @@ interface RegisterOptions {
|
||||
interface Video {
|
||||
isLive: boolean
|
||||
isLocal: boolean
|
||||
name: string
|
||||
originInstanceUrl: string
|
||||
uuid: string
|
||||
}
|
||||
|
@ -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,134 @@ 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<HTMLAnchorElement> =
|
||||
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<void> => {
|
||||
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() + '/webchat/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 {
|
||||
const rooms = json.rooms.sort((a, b) => {
|
||||
const timestampA = a.lasttimestamp ?? 0
|
||||
const timestampB = b.lasttimestamp ?? 0
|
||||
if (timestampA === timestampB) {
|
||||
return a.name.localeCompare(b.name)
|
||||
} else if (timestampA < timestampB) {
|
||||
return 1
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
})
|
||||
|
||||
container.textContent = ''
|
||||
const table = document.createElement('table')
|
||||
table.classList.add('peertube-plugin-livechat-prosody-list-rooms')
|
||||
container.append(table)
|
||||
// TODO: translate labels.
|
||||
const labels: any = {
|
||||
RoomName: 'Room name',
|
||||
RoomDescription: 'Room description',
|
||||
NotFound: 'Not found',
|
||||
Video: 'Video',
|
||||
LastActivity: 'Last activity'
|
||||
}
|
||||
|
||||
const titleLineEl = document.createElement('tr')
|
||||
const titleNameEl = document.createElement('th')
|
||||
titleNameEl.textContent = labels.RoomName
|
||||
const titleDescriptionEl = document.createElement('th')
|
||||
titleDescriptionEl.textContent = labels.RoomDescription
|
||||
const titleVideoEl = document.createElement('th')
|
||||
titleVideoEl.textContent = labels.Video
|
||||
const titleLastActivityEl = document.createElement('th')
|
||||
titleLastActivityEl.textContent = labels.LastActivity
|
||||
titleLineEl.append(titleNameEl)
|
||||
titleLineEl.append(titleDescriptionEl)
|
||||
titleLineEl.append(titleVideoEl)
|
||||
titleLineEl.append(titleLastActivityEl)
|
||||
table.append(titleLineEl)
|
||||
rooms.forEach(room => {
|
||||
const uuid = room.localpart
|
||||
const href = getBaseRoute() + '/webchat/room/' + encodeURIComponent(uuid)
|
||||
const lineEl = document.createElement('tr')
|
||||
const nameEl = document.createElement('td')
|
||||
const aEl = document.createElement('a')
|
||||
aEl.textContent = room.name
|
||||
aEl.target = '_blank'
|
||||
const descriptionEl = document.createElement('td')
|
||||
descriptionEl.textContent = room.description
|
||||
const videoEl = document.createElement('td')
|
||||
const lastActivityEl = document.createElement('td')
|
||||
if (room.lasttimestamp && (typeof room.lasttimestamp === 'number')) {
|
||||
const date = new Date(room.lasttimestamp * 1000)
|
||||
lastActivityEl.textContent = date.toLocaleDateString() + ' ' + date.toLocaleTimeString()
|
||||
}
|
||||
nameEl.append(aEl)
|
||||
lineEl.append(nameEl)
|
||||
lineEl.append(descriptionEl)
|
||||
lineEl.append(videoEl)
|
||||
lineEl.append(lastActivityEl)
|
||||
table.append(lineEl)
|
||||
|
||||
if (/^[a-zA-A0-9-]+$/.test(uuid)) {
|
||||
const p = fetch('/api/v1/videos/' + uuid, {
|
||||
method: 'GET',
|
||||
headers: peertubeHelpers.getAuthHeader()
|
||||
})
|
||||
p.then(async res => {
|
||||
if (!res.ok) {
|
||||
videoEl.textContent = labels.NotFound
|
||||
return
|
||||
}
|
||||
const video: Video | undefined = await res.json()
|
||||
if (!video) {
|
||||
videoEl.textContent = labels.NotFound
|
||||
return
|
||||
}
|
||||
|
||||
aEl.href = href
|
||||
const aVideoEl = document.createElement('a')
|
||||
aVideoEl.textContent = video.name
|
||||
aVideoEl.target = '_blank'
|
||||
aVideoEl.href = '/videos/watch/' + uuid
|
||||
videoEl.append(aVideoEl)
|
||||
}, () => {
|
||||
console.error('[peertube-plugin-livechat] Failed to retrieve video ' + uuid)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
peertubeHelpers.notifier.error('Room list failed')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
registerSettingsScript({
|
||||
@ -42,7 +170,15 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re
|
||||
case 'prosody-port':
|
||||
case 'prosody-peertube-uri':
|
||||
case 'chat-type-help-builtin-prosody':
|
||||
case 'prosody-list-rooms':
|
||||
case 'prosody-advanced':
|
||||
case 'prosody-c2s':
|
||||
return options.formValues['chat-type'] !== ('builtin-prosody' as ChatType)
|
||||
case 'prosody-c2s-port':
|
||||
return !(
|
||||
options.formValues['chat-type'] === ('builtin-prosody' as ChatType) &&
|
||||
options.formValues['prosody-c2s'] === true
|
||||
)
|
||||
case 'chat-server':
|
||||
case 'chat-room':
|
||||
case 'chat-bosh-uri':
|
||||
|
@ -61,6 +61,27 @@ This is the port that the Prosody server will use. By default it is set to 52800
|
||||
These settings are common with other chat modes.
|
||||
Here is the documentation: [common settings](./common.md).
|
||||
|
||||
### Prosody advanced settings
|
||||
|
||||
#### Enable client to server connections
|
||||
|
||||
This setting enable XMPP clients to connect to the builtin Prosody server.
|
||||
For now, this option **only allows connections from localhost clients**.
|
||||
|
||||
As example, this option can allow an instance of Matterbridge (once it could use anonymous login) *on the same machine* to bridge your chat with another services like a Matrix room.
|
||||
|
||||
##### Prosody client to server port
|
||||
|
||||
The port that will be used by the c2s module of the builtin Prosody server.
|
||||
XMPP clients shall use this port to connect.
|
||||
Change it if this port is already in use on your server.
|
||||
|
||||
## Moderation
|
||||
|
||||
You can list all existing chatrooms: in the plugin settings screen, there is a button «List rooms».
|
||||
|
||||
You can delete old rooms: join the room, and use the menu on the top to destroy the room.
|
||||
|
||||
## Notes
|
||||
|
||||
All instance moderators and admins will be owner for created chat rooms.
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "peertube-plugin-livechat",
|
||||
"description": "PeerTube plugin livechat",
|
||||
"version": "3.1.0",
|
||||
"version": "3.2.0",
|
||||
"author": "John Livingston",
|
||||
"bugs": "https://github.com/JohnXLivingston/peertube-plugin-livechat/issues",
|
||||
"clientScripts": [
|
||||
|
@ -0,0 +1,5 @@
|
||||
# mod_http_peertubelivechat_list_rooms
|
||||
|
||||
This module is a custom module that allows Peertube server to list chat rooms.
|
||||
|
||||
This module is part of peertube-plugin-livechat, and is under the same LICENSE.
|
@ -0,0 +1,62 @@
|
||||
local json = require "util.json";
|
||||
local jid_split = require"util.jid".split;
|
||||
local array = require "util.array";
|
||||
|
||||
local mod_muc = module:depends"muc";
|
||||
local all_rooms = rawget(mod_muc, "all_rooms")
|
||||
|
||||
module:depends"http";
|
||||
|
||||
function check_auth(routes)
|
||||
local function check_request_auth(event)
|
||||
local apikey = module:get_option_string("peertubelivechat_list_rooms_apikey", "")
|
||||
if apikey == "" then
|
||||
return false, 500;
|
||||
end
|
||||
if event.request.headers.authorization ~= "Bearer " .. apikey then
|
||||
return false, 401;
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
for route, handler in pairs(routes) do
|
||||
routes[route] = function (event, ...)
|
||||
local permit, code = check_request_auth(event);
|
||||
if not permit then
|
||||
return code;
|
||||
end
|
||||
return handler(event, ...);
|
||||
end;
|
||||
end
|
||||
return routes;
|
||||
end
|
||||
|
||||
local function list_rooms(event)
|
||||
local request, response = event.request, event.response;
|
||||
local rooms_json = array();
|
||||
for room in all_rooms() do
|
||||
local localpart = jid_split(room.jid);
|
||||
local history = room._history;
|
||||
local lasttimestamp;
|
||||
if history ~= nil and #history > 0 then
|
||||
lasttimestamp = history[#history].timestamp;
|
||||
end
|
||||
rooms_json:push({
|
||||
jid = room.jid;
|
||||
localpart = localpart;
|
||||
name = room:get_name() or localpart;
|
||||
lang = room.get_language and room:get_language();
|
||||
description = room:get_description();
|
||||
lasttimestamp = lasttimestamp;
|
||||
})
|
||||
end
|
||||
|
||||
event.response.headers["Content-Type"] = "application/json";
|
||||
return json.encode_array(rooms_json);
|
||||
end
|
||||
|
||||
module:provides("http", {
|
||||
route = check_auth {
|
||||
["GET /list-rooms"] = list_rooms;
|
||||
};
|
||||
});
|
@ -21,12 +21,14 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
|
||||
// FIXME: these tests are very similar to tests in testProsodyCorrectlyRunning. Remove from here?
|
||||
// Testing the prosody config file.
|
||||
let prosodyPort: string
|
||||
let prosodyHost: string
|
||||
try {
|
||||
const wantedConfig = await getProsodyConfig(options)
|
||||
const filePath = wantedConfig.paths.config
|
||||
|
||||
result.messages.push(`Prosody will run on port '${wantedConfig.port}'`)
|
||||
prosodyPort = wantedConfig.port
|
||||
prosodyHost = wantedConfig.host
|
||||
|
||||
result.messages.push(`Prosody will use ${wantedConfig.baseApiUrl} as base uri from api calls`)
|
||||
|
||||
@ -99,7 +101,8 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
|
||||
const testResult = await got(apiUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
authorization: 'Bearer ' + await getAPIKey(options)
|
||||
authorization: 'Bearer ' + await getAPIKey(options),
|
||||
host: prosodyHost
|
||||
},
|
||||
responseType: 'json',
|
||||
resolveBodyOnly: true
|
||||
@ -120,7 +123,8 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
|
||||
const testResult = await got(apiUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
authorization: 'Bearer ' + await getAPIKey(options)
|
||||
authorization: 'Bearer ' + await getAPIKey(options),
|
||||
host: prosodyHost
|
||||
},
|
||||
responseType: 'json',
|
||||
resolveBodyOnly: true
|
||||
|
@ -66,6 +66,7 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise<Pro
|
||||
interface ProsodyConfig {
|
||||
content: string
|
||||
paths: ProsodyFilePaths
|
||||
host: string
|
||||
port: string
|
||||
baseApiUrl: string
|
||||
}
|
||||
@ -77,6 +78,7 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
|
||||
if (!/^\d+$/.test(port)) {
|
||||
throw new Error('Invalid port')
|
||||
}
|
||||
const enableC2s = (await options.settingsManager.getSetting('prosody-c2s') as boolean) || false
|
||||
const prosodyDomain = await getProsodyDomain(options)
|
||||
const paths = await getProsodyFilePaths(options)
|
||||
|
||||
@ -99,11 +101,21 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
|
||||
config.usePeertubeBosh(prosodyDomain, port)
|
||||
config.useMucHttpDefault(roomApiUrl)
|
||||
|
||||
if (enableC2s) {
|
||||
const c2sPort = (await options.settingsManager.getSetting('prosody-c2s-port') as string) || '52822'
|
||||
if (!/^\d+$/.test(c2sPort)) {
|
||||
throw new Error('Invalid c2s port')
|
||||
}
|
||||
config.useC2S(c2sPort)
|
||||
}
|
||||
|
||||
// TODO: add a settings so that admin can choose? (on/off and duration)
|
||||
config.useMam('1w') // Remove archived messages after 1 week
|
||||
// TODO: add a settings to choose?
|
||||
config.useDefaultPersistent()
|
||||
|
||||
config.useListRoomsApi(apikey)
|
||||
|
||||
config.useTestModule(apikey, testApiUrl)
|
||||
|
||||
let logLevel: ProsodyLogLevel | undefined
|
||||
@ -126,7 +138,8 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
|
||||
content,
|
||||
paths,
|
||||
port,
|
||||
baseApiUrl
|
||||
baseApiUrl,
|
||||
host: prosodyDomain
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,6 +190,8 @@ class ProsodyConfigContent {
|
||||
this.anon.set('http_external_url', 'http://' + prosodyDomain)
|
||||
|
||||
this.muc.set('restrict_room_creation', 'local')
|
||||
this.muc.set('http_host', prosodyDomain)
|
||||
this.muc.set('http_external_url', 'http://' + prosodyDomain)
|
||||
|
||||
if (this.authenticated) {
|
||||
this.authenticated.set('trusted_proxies', ['127.0.0.1', '::1'])
|
||||
@ -201,6 +203,10 @@ class ProsodyConfigContent {
|
||||
}
|
||||
}
|
||||
|
||||
useC2S (c2sPort: string): void {
|
||||
this.global.set('c2s_ports', [c2sPort])
|
||||
}
|
||||
|
||||
useMucHttpDefault (url: string): void {
|
||||
this.muc.add('modules_enabled', 'muc_http_defaults')
|
||||
this.muc.add('muc_create_api_url', url)
|
||||
@ -236,10 +242,15 @@ class ProsodyConfigContent {
|
||||
this.muc.set('muc_room_default_persistent', true)
|
||||
}
|
||||
|
||||
useListRoomsApi (apikey: string): void {
|
||||
this.muc.add('modules_enabled', 'http_peertubelivechat_list_rooms')
|
||||
this.muc.set('peertubelivechat_list_rooms_apikey', apikey)
|
||||
}
|
||||
|
||||
useTestModule (prosodyApikey: string, apiurl: string): void {
|
||||
this.global.add('modules_enabled', 'http_peertubelivechat_test')
|
||||
this.global.set('peertubelivechat_test_apikey', prosodyApikey)
|
||||
this.global.set('peertubelivechat_test_peertube_api_url', apiurl)
|
||||
this.muc.add('modules_enabled', 'http_peertubelivechat_test')
|
||||
this.muc.set('peertubelivechat_test_apikey', prosodyApikey)
|
||||
this.muc.set('peertubelivechat_test_peertube_api_url', apiurl)
|
||||
}
|
||||
|
||||
setLog (level: ProsodyLogLevel, syslog?: ProsodyLogLevel[]): void {
|
||||
|
@ -195,7 +195,10 @@ async function ensureProsodyRunning (options: RegisterServerOptions): Promise<vo
|
||||
})
|
||||
|
||||
// Set the http-bind route.
|
||||
changeHttpBindRoute(options, config.port)
|
||||
changeHttpBindRoute(options, {
|
||||
host: config.host,
|
||||
port: config.port
|
||||
})
|
||||
|
||||
async function sleep (ms: number): Promise<any> {
|
||||
return new Promise((resolve) => {
|
||||
|
@ -1,16 +1,23 @@
|
||||
import type { Router, RequestHandler, Request, Response, NextFunction } from 'express'
|
||||
import type { ProxyOptions } from 'express-http-proxy'
|
||||
import type { ChatType } from '../../../shared/lib/types'
|
||||
import { getBaseRouterRoute, getBaseStaticRoute } from '../helpers'
|
||||
import type { ChatType, ProsodyListRoomsResult } from '../../../shared/lib/types'
|
||||
import { getBaseRouterRoute, getBaseStaticRoute, isUserAdmin } from '../helpers'
|
||||
import { asyncMiddleware } from '../middlewares/async'
|
||||
import { getProsodyDomain } from '../prosody/config/domain'
|
||||
import { getAPIKey } from '../apikey'
|
||||
import * as path from 'path'
|
||||
const bodyParser = require('body-parser')
|
||||
const got = require('got')
|
||||
|
||||
const fs = require('fs').promises
|
||||
const proxy = require('express-http-proxy')
|
||||
|
||||
let httpBindRoute: RequestHandler
|
||||
interface ProsodyHttpBindInfo {
|
||||
host: string
|
||||
port: string
|
||||
}
|
||||
let currentProsodyHttpBindInfo: ProsodyHttpBindInfo | null = null
|
||||
|
||||
async function initWebchatRouter (options: RegisterServerOptions): Promise<Router> {
|
||||
const {
|
||||
@ -97,22 +104,76 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
|
||||
httpBindRoute(req, res, next)
|
||||
}
|
||||
)
|
||||
|
||||
router.get('/prosody-list-rooms', asyncMiddleware(
|
||||
async (req: Request, res: Response, _next: NextFunction) => {
|
||||
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
|
||||
}
|
||||
|
||||
if (!currentProsodyHttpBindInfo) {
|
||||
throw new Error('It seems that prosody is not binded... Cant list rooms.')
|
||||
}
|
||||
const apiUrl = `http://localhost:${currentProsodyHttpBindInfo.port}/peertubelivechat_list_rooms/list-rooms`
|
||||
peertubeHelpers.logger.debug('Calling list rooms API on url: ' + apiUrl)
|
||||
const rooms = await got(apiUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
authorization: 'Bearer ' + await getAPIKey(options),
|
||||
host: currentProsodyHttpBindInfo.host
|
||||
},
|
||||
responseType: 'json',
|
||||
resolveBodyOnly: true
|
||||
})
|
||||
|
||||
res.status(200)
|
||||
const r: ProsodyListRoomsResult = {
|
||||
ok: true,
|
||||
rooms: rooms
|
||||
}
|
||||
res.json(r)
|
||||
}
|
||||
))
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
function changeHttpBindRoute ({ peertubeHelpers }: RegisterServerOptions, port: string | null): void {
|
||||
function changeHttpBindRoute (
|
||||
{ peertubeHelpers }: RegisterServerOptions,
|
||||
prosodyHttpBindInfo: ProsodyHttpBindInfo | null
|
||||
): void {
|
||||
const logger = peertubeHelpers.logger
|
||||
logger.info('Changing http-bind port for ' + (port ?? 'null'))
|
||||
if (port !== null && !/^\d+$/.test(port)) {
|
||||
logger.error('Port is not valid. Replacing by null')
|
||||
port = null
|
||||
if (prosodyHttpBindInfo && !/^\d+$/.test(prosodyHttpBindInfo.port)) {
|
||||
logger.error(`Port '${prosodyHttpBindInfo.port}' is not valid. Replacing by null`)
|
||||
prosodyHttpBindInfo = null
|
||||
}
|
||||
if (port === null) {
|
||||
|
||||
if (!prosodyHttpBindInfo) {
|
||||
logger.info('Changing http-bind port for null')
|
||||
currentProsodyHttpBindInfo = null
|
||||
httpBindRoute = (_req: Request, res: Response, _next: NextFunction) => {
|
||||
res.status(404)
|
||||
res.send('Not found')
|
||||
}
|
||||
} else {
|
||||
logger.info('Changing http-bind port for ' + prosodyHttpBindInfo.port + ', on host ' + prosodyHttpBindInfo.host)
|
||||
const options: ProxyOptions = {
|
||||
https: false,
|
||||
proxyReqPathResolver: async (_req: Request): Promise<string> => {
|
||||
@ -122,7 +183,8 @@ function changeHttpBindRoute ({ peertubeHelpers }: RegisterServerOptions, port:
|
||||
parseReqBody: true // Note that setting this to false overrides reqAsBuffer and reqBodyEncoding below.
|
||||
// FIXME: should we remove cookies?
|
||||
}
|
||||
httpBindRoute = proxy('http://localhost:' + port, options)
|
||||
currentProsodyHttpBindInfo = prosodyHttpBindInfo
|
||||
httpBindRoute = proxy('http://localhost:' + prosodyHttpBindInfo.port, options)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,13 @@ Please read the
|
||||
private: true
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'prosody-list-rooms',
|
||||
label: 'List existing rooms',
|
||||
type: 'html',
|
||||
descriptionHTML: '<a class="peertube-plugin-livechat-prosody-list-rooms">List rooms</a>',
|
||||
private: true
|
||||
})
|
||||
registerSetting({
|
||||
name: 'prosody-port',
|
||||
label: 'Prosody port',
|
||||
@ -103,18 +110,6 @@ Change it if this port is already in use on your server.<br>
|
||||
You can close this port on your firewall, it will not be accessed from the outer world.`
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'prosody-peertube-uri',
|
||||
label: 'Peertube url for API calls',
|
||||
type: 'input',
|
||||
default: '',
|
||||
private: true,
|
||||
descriptionHTML:
|
||||
`Please let this settings empty if you don't know what you are doing.<br>
|
||||
In some rare case, Prosody can't call Peertube's API from its public URI.
|
||||
You can use this field to customise Peertube's URI for Prosody modules (for example with «http://localhost:9000»).`
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'chat-server',
|
||||
label: 'XMPP service server',
|
||||
@ -269,6 +264,50 @@ Example: height:400px;`,
|
||||
private: false
|
||||
})
|
||||
|
||||
// ********** Built-in Prosody advanced settings
|
||||
registerSetting({
|
||||
name: 'prosody-advanced',
|
||||
type: 'html',
|
||||
private: true,
|
||||
descriptionHTML: '<h3>Prosody advanced settings</h3>'
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'prosody-peertube-uri',
|
||||
label: 'Peertube url for API calls',
|
||||
type: 'input',
|
||||
default: '',
|
||||
private: true,
|
||||
descriptionHTML:
|
||||
`Please let this settings empty if you don't know what you are doing.<br>
|
||||
In some rare case, Prosody can't call Peertube's API from its public URI.
|
||||
You can use this field to customise Peertube's URI for Prosody modules (for example with «http://localhost:9000»).`
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'prosody-c2s',
|
||||
label: 'Enable client to server connections',
|
||||
type: 'input-checkbox',
|
||||
default: false,
|
||||
private: true,
|
||||
descriptionHTML:
|
||||
`Enable XMPP clients to connect to the builtin Prosody server.<br>
|
||||
This option alone only allows connections from localhost clients.`
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'prosody-c2s-port',
|
||||
label: 'Prosody client to server port',
|
||||
type: 'input',
|
||||
default: '52822',
|
||||
private: true,
|
||||
descriptionHTML:
|
||||
`The port that will be used by the c2s module of the builtin Prosody server.<br>
|
||||
XMPP clients shall use this port to connect.<br>
|
||||
Change it if this port is already in use on your server.<br>
|
||||
Keep it close this port on your firewall for now, it will not be accessed from the outer world.`
|
||||
})
|
||||
|
||||
// ********** settings changes management
|
||||
settingsManager.onSettingsChange(async (settings: any) => {
|
||||
if ('chat-type' in settings) {
|
||||
|
@ -1,5 +1,25 @@
|
||||
type ChatType = 'disabled' | 'builtin-prosody' | 'builtin-converse' | 'external-uri'
|
||||
|
||||
export {
|
||||
ChatType
|
||||
interface ProsodyListRoomsResultError {
|
||||
ok: false
|
||||
error: string
|
||||
}
|
||||
|
||||
interface ProsodyListRoomsResultSuccess {
|
||||
ok: true
|
||||
rooms: Array<{
|
||||
jid: string
|
||||
localpart: string
|
||||
name: string
|
||||
lang: string
|
||||
description: string
|
||||
lasttimestamp?: number
|
||||
}>
|
||||
}
|
||||
|
||||
type ProsodyListRoomsResult = ProsodyListRoomsResultError | ProsodyListRoomsResultSuccess
|
||||
|
||||
export {
|
||||
ChatType,
|
||||
ProsodyListRoomsResult
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user