diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea78..f06dcaff 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,7 +3,7 @@ name: Bug report about: Create a report to help us improve title: '' labels: '' -assignees: '' +assignees: JohnXLivingston --- @@ -23,6 +23,16 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. + +**Server (please complete the following information):** + - OS version [e.g. Debian 10, ...]: + - Peertube version: + - Peertube installation type [e.g. standard, docker, ...]: + - peertube-plugin-livechat version: + +**Plugin diagnostic:** +If this is a server setup issue, please go to the plugin settings, click on «launch diagnostic», and copy/paste the result. + **Desktop (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] diff --git a/CHANGELOG.md b/CHANGELOG.md index fb8696eb..769cc853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ # Changelog +## v3.2.0 + +... + ## v3.1.0 -... +### Features + +* Builtin Prosody: optional settings to change the url for Prosody's API calls. +* Diagnostic tool: testing API communication from Peertube to Prosody. +* Diagnostic tool: testing API communication from Prosody to Peertube. +* Diagnostic tool: correctly parse Prosody nightly build versions. ## v3.0.0 diff --git a/client/admin-plugin-client-plugin.ts b/client/admin-plugin-client-plugin.ts index 604c4fb8..942fdffb 100644 --- a/client/admin-plugin-client-plugin.ts +++ b/client/admin-plugin-client-plugin.ts @@ -111,6 +111,7 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re case 'chat-type-help-disabled': return options.formValues['chat-type'] !== ('disabled' as ChatType) case 'prosody-port': + case 'prosody-peertube-uri': case 'chat-type-help-builtin-prosody': case 'prosody-list-rooms': return options.formValues['chat-type'] !== ('builtin-prosody' as ChatType) diff --git a/package-lock.json b/package-lock.json index 61f77d30..2f160e24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "peertube-plugin-livechat", - "version": "3.0.0", + "version": "3.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 46c243e3..7fb12978 100644 --- a/package.json +++ b/package.json @@ -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": [ diff --git a/prosody-modules/mod_http_peertubelivechat_test/README.md b/prosody-modules/mod_http_peertubelivechat_test/README.md new file mode 100644 index 00000000..64903e49 --- /dev/null +++ b/prosody-modules/mod_http_peertubelivechat_test/README.md @@ -0,0 +1,5 @@ +# mod_http_peertubelivechat_test + +This module is a custom module that allows Peertube to test communication with Prosody. + +This module is part of peertube-plugin-livechat, and is under the same LICENSE. diff --git a/prosody-modules/mod_http_peertubelivechat_test/mod_http_peertubelivechat_test.lua b/prosody-modules/mod_http_peertubelivechat_test/mod_http_peertubelivechat_test.lua new file mode 100644 index 00000000..dd4d0576 --- /dev/null +++ b/prosody-modules/mod_http_peertubelivechat_test/mod_http_peertubelivechat_test.lua @@ -0,0 +1,87 @@ +local json = require "util.json"; +local async = require "util.async"; +local http = require "net.http"; + +module:depends"http"; + +local apikey = assert(module:get_option_string("peertubelivechat_test_apikey", nil), "'peertubelivechat_test_apikey' is a required option"); +local peertube_url = assert(module:get_option_string("peertubelivechat_test_peertube_api_url", nil), "'peertubelivechat_test_peertube_api_url' is a required option"); + +local ex = { + headers = { + accept = "application/json"; + } +}; + +local function check_auth(routes) + local function check_request_auth(event) + 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 test_peertube_prosody(event) + local request, response = event.request, event.response; + local json_response = { + ok = true; + } + event.response.headers["Content-Type"] = "application/json"; + return json.encode(json_response); +end + +local function test_prosody_peertube(event) + local request, response = event.request, event.response; + + local ret, err; + http.request(peertube_url, ex, function (body, code) + if math.floor(code / 100) == 2 then + local parsed, parse_err = json.decode(body); + if not parsed then + module:log("debug", "Got invalid JSON from %s: %s", peertube_url, parse_err); + err = problems.format; + else + ret = parsed; + end + else + module:log("debug", "Rejected by API: ", body); + err = "Rejected by API"; + end + + local json_response; + if not ret then + json_response = { + ok = false; + error = err; + }; + else + json_response = ret; + end + response:send(json.encode(json_response)); + end); + + event.response.headers["Content-Type"] = "application/json"; + return true +end + +module:provides("http", { + route = check_auth { + ["GET /test-peertube-prosody"] = test_peertube_prosody; + ["GET /test-prosody-peertube"] = test_prosody_peertube; + }; +}); diff --git a/server/lib/diagnostic/prosody.ts b/server/lib/diagnostic/prosody.ts index 11e8885f..f069eb54 100644 --- a/server/lib/diagnostic/prosody.ts +++ b/server/lib/diagnostic/prosody.ts @@ -1,8 +1,11 @@ import { getProsodyConfig, getWorkingDir } from '../prosody/config' import { getProsodyAbout, testProsodyCorrectlyRunning } from '../prosody/ctl' import { newResult, TestResult } from './utils' +import { getAPIKey } from '../apikey' import * as fs from 'fs' +const got = require('got') + export async function diagProsody (test: string, options: RegisterServerOptions): Promise { const result = newResult(test) result.label = 'Builtin Prosody and ConverseJS' @@ -17,11 +20,15 @@ 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 try { const wantedConfig = await getProsodyConfig(options) const filePath = wantedConfig.paths.config result.messages.push(`Prosody will run on port '${wantedConfig.port}'`) + prosodyPort = wantedConfig.port + + result.messages.push(`Prosody will use ${wantedConfig.baseApiUrl} as base uri from api calls`) result.messages.push(`Prosody modules path will be '${wantedConfig.paths.modules}'`) @@ -67,7 +74,7 @@ export async function diagProsody (test: string, options: RegisterServerOptions) return result } - const versionMatches = about.match(/^Prosody\s*(\d+)\.(\d+)\.(\d+)\s*$/mi) + const versionMatches = about.match(/^Prosody\s*(\d+)\.(\d+)(?:\.(\d+)| (nightly build \d+.*))\s*$/mi) if (!versionMatches) { result.messages.push({ level: 'error', @@ -77,7 +84,7 @@ export async function diagProsody (test: string, options: RegisterServerOptions) } else { const major = versionMatches[1] const minor = versionMatches[2] - const patch = versionMatches[3] + const patch = versionMatches[3] ?? versionMatches[4] result.messages.push(`Prosody version is ${major}.${minor}.${patch}`) if (major !== '0' && minor !== '11') { result.messages.push({ @@ -87,6 +94,48 @@ export async function diagProsody (test: string, options: RegisterServerOptions) } } + try { + const apiUrl = `http://localhost:${prosodyPort}/peertubelivechat_test/test-peertube-prosody` + const testResult = await got(apiUrl, { + method: 'GET', + headers: { + authorization: 'Bearer ' + await getAPIKey(options) + }, + responseType: 'json', + resolveBodyOnly: true + }) + if (testResult.ok === true) { + result.messages.push('API Peertube -> Prosody is OK') + } else { + result.messages.push('API Peertube -> Prosody is KO. Response was: ' + JSON.stringify(testResult)) + return result + } + } catch (error) { + result.messages.push('Error when calling Prosody test api (test-peertube-prosody): ' + (error as string)) + return result + } + + try { + const apiUrl = `http://localhost:${prosodyPort}/peertubelivechat_test/test-prosody-peertube` + const testResult = await got(apiUrl, { + method: 'GET', + headers: { + authorization: 'Bearer ' + await getAPIKey(options) + }, + responseType: 'json', + resolveBodyOnly: true + }) + if (testResult.ok === true) { + result.messages.push('API Prosody -> Peertube is OK') + } else { + result.messages.push('API Prosody -> Peertube is KO. Response was: ' + JSON.stringify(testResult)) + return result + } + } catch (error) { + result.messages.push('Error when calling Prosody test api (test-prosody-peertube): ' + (error as string)) + return result + } + result.ok = true return result } diff --git a/server/lib/prosody/config.ts b/server/lib/prosody/config.ts index 33c15a00..85e3e7f0 100644 --- a/server/lib/prosody/config.ts +++ b/server/lib/prosody/config.ts @@ -67,6 +67,7 @@ interface ProsodyConfig { content: string paths: ProsodyFilePaths port: string + baseApiUrl: string } async function getProsodyConfig (options: RegisterServerOptions): Promise { const logger = options.peertubeHelpers.logger @@ -80,11 +81,18 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise { const router = getRouter() const logger = peertubeHelpers.logger + router.get('/test', asyncMiddleware([ + getCheckAPIKeyMiddleware(options), + async (req: Request, res: Response, _next: NextFunction) => { + logger.info('Test api call') + res.json({ ok: true }) + } + ])) + router.get('/room', asyncMiddleware([ getCheckAPIKeyMiddleware(options), async (req: Request, res: Response, _next: NextFunction) => { diff --git a/server/lib/settings.ts b/server/lib/settings.ts index 29ba67f1..a1462617 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -110,6 +110,18 @@ Change it if this port is already in use on your server.
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.
+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',