Fix #48: Proper 404 and 403 pages when trying to open non-existant chatroom (WIP).
This commit is contained in:
parent
972306aa3e
commit
0719d25f35
@ -20,6 +20,7 @@ TODO: https://github.com/JohnXLivingston/peertube-plugin-livechat/issues/48
|
||||
* Some code refactoring.
|
||||
* New translations: Galician.
|
||||
* Fix slow mode: focus was lost when textarea got disabled, so it could trigger some Peertube events if the user type some text.
|
||||
* #48: Proper 404 and 403 pages when trying to open non-existant chatroom.
|
||||
|
||||
## 8.4.0
|
||||
|
||||
|
@ -207,3 +207,18 @@ table.peertube-plugin-livechat-prosody-list-rooms td {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.peertube-plugin-livechat-error-message {
|
||||
/* display an error block (page not found, ...) */
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
padding-top: 50px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.peertube-plugin-livechat-container {
|
||||
.peertube-plugin-livechat-error-message {
|
||||
max-width: 30vw;
|
||||
}
|
||||
}
|
||||
|
1
client/@types/global.d.ts
vendored
1
client/@types/global.d.ts
vendored
@ -76,3 +76,4 @@ declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_BOT_NICKNAME: string
|
||||
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_FOR_MORE_INFO: string
|
||||
|
||||
declare const LOC_INVALID_VALUE: string
|
||||
declare const LOC_CHATROOM_NOT_ACCESSIBLE: string
|
||||
|
@ -26,8 +26,12 @@ async function registerRoom (clientOptions: RegisterClientOptions): Promise<void
|
||||
await displayConverseJS(clientOptions, container, roomKey, 'peertube-fullpage', forceType)
|
||||
} catch (err) {
|
||||
console.error('[peertube-plugin-livechat] ' + (err as string))
|
||||
// FIXME: do a better error page.
|
||||
rootEl.innerText = await peertubeHelpers.translate(LOC_NOT_FOUND)
|
||||
// Displaying an error page.
|
||||
rootEl.innerHTML = ''
|
||||
const message = document.createElement('div')
|
||||
message.classList.add('peertube-plugin-livechat-error-message')
|
||||
message.innerText = await peertubeHelpers.translate(LOC_CHATROOM_NOT_ACCESSIBLE)
|
||||
rootEl.append(message)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -155,7 +155,7 @@ async function displayConverseJS (
|
||||
}
|
||||
)
|
||||
if (!response.ok) {
|
||||
throw new Error('Can\'t get channel configuration options.')
|
||||
throw new Error('Can\'t get room configuration.')
|
||||
}
|
||||
const converseJSParams: InitConverseJSParams = await (response).json()
|
||||
|
||||
|
@ -214,7 +214,15 @@ function register (registerOptions: RegisterClientOptions): void {
|
||||
// Loading converseJS...
|
||||
await displayConverseJS(registerOptions, container, roomkey, 'peertube-video', false)
|
||||
} catch (err) {
|
||||
// Displaying an error page.
|
||||
if (container) {
|
||||
const message = document.createElement('div')
|
||||
message.classList.add('peertube-plugin-livechat-error-message')
|
||||
message.innerText = await peertubeHelpers.translate(LOC_CHATROOM_NOT_ACCESSIBLE)
|
||||
container.append(message)
|
||||
}
|
||||
|
||||
hackStyles(false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,7 +237,9 @@ function register (registerOptions: RegisterClientOptions): void {
|
||||
if (window.converse?.livechatDisconnect) { window.converse.livechatDisconnect() }
|
||||
|
||||
// Removing from the DOM
|
||||
container.querySelectorAll('converse-root, .livechat-spinner').forEach(dom => dom.remove())
|
||||
container.querySelectorAll(
|
||||
'converse-root, .livechat-spinner, .peertube-plugin-livechat-error-message'
|
||||
).forEach(dom => dom.remove())
|
||||
|
||||
container.setAttribute('peertube-plugin-livechat-state', 'closed')
|
||||
|
||||
|
@ -390,3 +390,5 @@ livechat_configuration_channel_bot_nickname: "Bot nickname"
|
||||
invalid_value: "Invalid value."
|
||||
|
||||
slow_mode_info: "Slow mode is enabled, users can send a message every %1$s seconds."
|
||||
|
||||
chatroom_not_accessible: "This chatroom does not exist, or is not accessible to you."
|
||||
|
20
package-lock.json
generated
20
package-lock.json
generated
@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"async": "^3.2.2",
|
||||
"decache": "^4.6.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"got": "^11.8.2",
|
||||
"http-proxy": "^1.18.1",
|
||||
"log-rotate": "^0.2.8",
|
||||
@ -22,6 +23,7 @@
|
||||
"@peertube/peertube-types": "^5.2.0",
|
||||
"@tsconfig/node12": "^1.0.9",
|
||||
"@types/async": "^3.2.9",
|
||||
"@types/escape-html": "^1.0.4",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/got": "^9.6.12",
|
||||
"@types/http-proxy": "^1.17.9",
|
||||
@ -3896,6 +3898,12 @@
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/escape-html": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.4.tgz",
|
||||
"integrity": "sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "4.17.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
|
||||
@ -6441,8 +6449,7 @@
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"dev": true
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
@ -15300,6 +15307,12 @@
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"@types/escape-html": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.4.tgz",
|
||||
"integrity": "sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
|
||||
@ -17251,8 +17264,7 @@
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"dev": true
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
|
@ -35,6 +35,7 @@
|
||||
"dependencies": {
|
||||
"async": "^3.2.2",
|
||||
"decache": "^4.6.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"got": "^11.8.2",
|
||||
"http-proxy": "^1.18.1",
|
||||
"log-rotate": "^0.2.8",
|
||||
@ -46,6 +47,7 @@
|
||||
"@peertube/peertube-types": "^5.2.0",
|
||||
"@tsconfig/node12": "^1.0.9",
|
||||
"@types/async": "^3.2.9",
|
||||
"@types/escape-html": "^1.0.4",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/got": "^9.6.12",
|
||||
"@types/http-proxy": "^1.17.9",
|
||||
|
@ -23,20 +23,32 @@ interface GetConverseJSParamsParams {
|
||||
* Returns an object describing the error if access can not be granted.
|
||||
* @param options server options
|
||||
* @param roomKey chat room key: video UUID (or channel id when forcetype is true)
|
||||
* @param params various parameters
|
||||
* @param userIsConnected true if user is connected. If undefined, bypass access tests.
|
||||
*/
|
||||
async function getConverseJSParams (
|
||||
options: RegisterServerOptionsV5,
|
||||
roomKey: string,
|
||||
params: GetConverseJSParamsParams
|
||||
params: GetConverseJSParamsParams,
|
||||
userIsConnected?: boolean
|
||||
): Promise<InitConverseJSParams | InitConverseJSParamsError> {
|
||||
const settings = await options.settingsManager.getSettings([
|
||||
'prosody-room-type',
|
||||
'disable-websocket',
|
||||
'converse-theme',
|
||||
'federation-no-remote-chat',
|
||||
'prosody-room-allow-s2s'
|
||||
'prosody-room-allow-s2s',
|
||||
'chat-no-anonymous'
|
||||
])
|
||||
|
||||
if (settings['chat-no-anonymous'] && userIsConnected === false) {
|
||||
return {
|
||||
isError: true,
|
||||
code: 403,
|
||||
message: 'You must be connected'
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
autoViewerMode, forceReadonly, transparent, converseJSTheme
|
||||
} = _interfaceParams(options, settings, params)
|
||||
@ -337,5 +349,6 @@ async function _localRoomJID (
|
||||
}
|
||||
|
||||
export {
|
||||
getConverseJSParams
|
||||
getConverseJSParams,
|
||||
InitConverseJSParamsError
|
||||
}
|
||||
|
@ -18,9 +18,17 @@ async function initConfigurationApiRouter (options: RegisterServerOptions, route
|
||||
router.get('/configuration/room/:roomKey', asyncMiddleware(
|
||||
async (req: Request, res: Response, _next: NextFunction): Promise<void> => {
|
||||
const roomKey = req.params.roomKey
|
||||
const initConverseJSParam = await getConverseJSParams(options, roomKey, {
|
||||
|
||||
const user = await options.peertubeHelpers.user.getAuthUser(res)
|
||||
|
||||
const initConverseJSParam = await getConverseJSParams(
|
||||
options,
|
||||
roomKey,
|
||||
{
|
||||
forcetype: req.query.forcetype === '1'
|
||||
})
|
||||
},
|
||||
!!user
|
||||
)
|
||||
if (('isError' in initConverseJSParam) && initConverseJSParam.isError) {
|
||||
res.sendStatus(initConverseJSParam.code)
|
||||
return
|
||||
|
@ -1,6 +1,8 @@
|
||||
import type { RegisterServerOptions } from '@peertube/peertube-types'
|
||||
import type { Router, Request, Response, NextFunction } from 'express'
|
||||
import type { ProsodyListRoomsResult, ProsodyListRoomsResultRoom } from '../../../shared/lib/types'
|
||||
import type {
|
||||
InitConverseJSParamsError, ProsodyListRoomsResult, ProsodyListRoomsResultRoom
|
||||
} from '../../../shared/lib/types'
|
||||
import { createProxyServer } from 'http-proxy'
|
||||
import { RegisterServerOptionsV5, isUserAdmin } from '../helpers'
|
||||
import { asyncMiddleware } from '../middlewares/async'
|
||||
@ -10,8 +12,11 @@ import { getConverseJSParams } from '../conversejs/params'
|
||||
import { setCurrentProsody, delCurrentProsody } from '../prosody/api/host'
|
||||
import { getChannelInfosById } from '../database/channel'
|
||||
import { listProsodyRooms } from '../prosody/api/manage-rooms'
|
||||
import { loc } from '../loc'
|
||||
import * as path from 'path'
|
||||
|
||||
const escapeHTML = require('escape-html')
|
||||
|
||||
const fs = require('fs').promises
|
||||
|
||||
interface ProsodyProxyInfo {
|
||||
@ -22,6 +27,14 @@ let currentHttpBindProxy: ReturnType<typeof createProxyServer> | null = null
|
||||
let currentWebsocketProxy: ReturnType<typeof createProxyServer> | null = null
|
||||
let currentS2SWebsocketProxy: ReturnType<typeof createProxyServer> | null = null
|
||||
|
||||
class LivechatError extends Error {
|
||||
livechatError: InitConverseJSParamsError
|
||||
constructor (e: InitConverseJSParamsError) {
|
||||
super(e.message)
|
||||
this.livechatError = e
|
||||
}
|
||||
}
|
||||
|
||||
async function initWebchatRouter (options: RegisterServerOptionsV5): Promise<Router> {
|
||||
const {
|
||||
getRouter,
|
||||
@ -33,8 +46,9 @@ async function initWebchatRouter (options: RegisterServerOptionsV5): Promise<Rou
|
||||
|
||||
const router: Router = getRouter()
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
router.get('/room/:roomKey', asyncMiddleware(
|
||||
async (req: Request, res: Response, _next: NextFunction): Promise<void> => {
|
||||
router.get('/room/:roomKey',
|
||||
asyncMiddleware(async (req: Request, res: Response, _next: NextFunction): Promise<void> => {
|
||||
try {
|
||||
res.removeHeader('X-Frame-Options') // this route can be opened in an iframe
|
||||
|
||||
const roomKey = req.params.roomKey
|
||||
@ -53,9 +67,7 @@ async function initWebchatRouter (options: RegisterServerOptionsV5): Promise<Rou
|
||||
})
|
||||
|
||||
if (('isError' in initConverseJSParam)) {
|
||||
res.status(initConverseJSParam.code)
|
||||
res.send(initConverseJSParam.message)
|
||||
return
|
||||
throw new LivechatError(initConverseJSParam)
|
||||
}
|
||||
|
||||
let page = '' + (converseJSIndex as string)
|
||||
@ -125,8 +137,22 @@ async function initWebchatRouter (options: RegisterServerOptionsV5): Promise<Rou
|
||||
res.status(200)
|
||||
res.type('html')
|
||||
res.send(page)
|
||||
} catch (err: LivechatError | any) {
|
||||
const code = err.livechatError?.code ?? 500
|
||||
const additionnalMessage: string = escapeHTML(err.livechatError?.message as string ?? '')
|
||||
const message: string = escapeHTML(loc('chatroom_not_accessible'))
|
||||
|
||||
res.status(code)
|
||||
res.send(`<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN"><html>
|
||||
<head><title>${message}</title></head>
|
||||
<body>
|
||||
<h1>${message}</h1>
|
||||
<p>${additionnalMessage}</p>
|
||||
</body>
|
||||
</html>`)
|
||||
}
|
||||
))
|
||||
})
|
||||
)
|
||||
|
||||
await disableProxyRoute(options)
|
||||
router.post('/http-bind',
|
||||
|
Loading…
x
Reference in New Issue
Block a user