Retrieving list rooms from prosody.

This commit is contained in:
John Livingston 2021-06-12 03:52:45 +02:00
parent 00bf5bd96b
commit 30d70e033e
13 changed files with 397 additions and 49 deletions

View File

@ -10,6 +10,7 @@
* New simpler settings screen. * New simpler settings screen.
* New field in live video form, to activate the webchat per video. There is a setting for enabling this new feature. * New field in live video form, to activate the webchat per video. There is a setting for enabling this new feature.
* When using the builtin prosody, there is a button to list existing chatrooms in the settings screen.
### Changes ### Changes
@ -18,9 +19,6 @@
* New settings * New settings
* By default, the «activate chat for all lives» is disabled (now that we can enable the webchat per video) * By default, the «activate chat for all lives» is disabled (now that we can enable the webchat per video)
### Fixes
* ...
## v2.3.1 ## v2.3.1

View File

@ -58,3 +58,7 @@
.peertube-plugin-livechat-error { .peertube-plugin-livechat-error {
color: red; color: red;
} }
table.peertube-plugin-livechat-prosody-list-rooms {
border: 1px solid black;
}

View File

@ -51,7 +51,7 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re
container.textContent = '...' container.textContent = '...'
listRoomsButton.after(container) listRoomsButton.after(container)
const response = await fetch(getBaseRoute() + '/settings/prosody-list-rooms', { const response = await fetch(getBaseRoute() + '/webchat/prosody-list-rooms', {
method: 'GET', method: 'GET',
headers: peertubeHelpers.getAuthHeader() headers: peertubeHelpers.getAuthHeader()
}) })
@ -63,18 +63,36 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re
container.textContent = json.error container.textContent = json.error
container.classList.add('peertube-plugin-livechat-error') container.classList.add('peertube-plugin-livechat-error')
} else { } else {
const rooms = json.rooms.sort((a, b) => a.name.localeCompare(b.name))
container.textContent = '' container.textContent = ''
const table = document.createElement('table') const table = document.createElement('table')
table.classList.add('peertube-plugin-livechat-prosody-list-rooms')
container.append(table) container.append(table)
json.rooms.forEach(room => { // TODO: translate labels.
const titleLineEl = document.createElement('tr')
const titleNameEl = document.createElement('th')
titleNameEl.textContent = 'Name'
const titleDescriptionEl = document.createElement('th')
titleDescriptionEl.textContent = 'Description'
titleLineEl.append(titleNameEl)
titleLineEl.append(titleDescriptionEl)
table.append(titleLineEl)
rooms.forEach(room => {
// TODO: get some informations about the video.
const uuid = room.localpart
const href = getBaseRoute() + '/webchat/room/' + encodeURIComponent(uuid)
const lineEl = document.createElement('tr') const lineEl = document.createElement('tr')
const nameEl = document.createElement('td') const nameEl = document.createElement('td')
const aEl = document.createElement('a') const aEl = document.createElement('a')
aEl.textContent = room.name aEl.textContent = room.name
aEl.href = room.href aEl.href = href
aEl.target = '_blank' aEl.target = '_blank'
const descriptionEl = document.createElement('td')
descriptionEl.textContent = room.description
nameEl.append(aEl) nameEl.append(aEl)
lineEl.append(nameEl) lineEl.append(nameEl)
lineEl.append(descriptionEl)
table.append(lineEl) table.append(lineEl)
}) })
} }

View File

@ -61,6 +61,12 @@ 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. These settings are common with other chat modes.
Here is the documentation: [common settings](./common.md). Here is the documentation: [common settings](./common.md).
## 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 ## Notes
All instance moderators and admins will be owner for created chat rooms. All instance moderators and admins will be owner for created chat rooms.

243
package-lock.json generated
View File

@ -129,6 +129,19 @@
"webpack-sources": "^1.0.0" "webpack-sources": "^1.0.0"
} }
}, },
"@sindresorhus/is": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz",
"integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g=="
},
"@szmarczak/http-timer": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
"integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
"requires": {
"defer-to-connect": "^2.0.0"
}
},
"@trysound/sax": { "@trysound/sax": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz",
@ -157,6 +170,17 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/cacheable-request": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz",
"integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==",
"requires": {
"@types/http-cache-semantics": "*",
"@types/keyv": "*",
"@types/node": "*",
"@types/responselike": "*"
}
},
"@types/connect": { "@types/connect": {
"version": "3.4.34", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
@ -198,6 +222,22 @@
"@types/range-parser": "*" "@types/range-parser": "*"
} }
}, },
"@types/got": {
"version": "9.6.11",
"resolved": "https://registry.npmjs.org/@types/got/-/got-9.6.11.tgz",
"integrity": "sha512-dr3IiDNg5TDesGyuwTrN77E1Cd7DCdmCFtEfSGqr83jMMtcwhf/SGPbN2goY4JUWQfvxwY56+e5tjfi+oXeSdA==",
"dev": true,
"requires": {
"@types/node": "*",
"@types/tough-cookie": "*",
"form-data": "^2.5.0"
}
},
"@types/http-cache-semantics": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz",
"integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A=="
},
"@types/json-schema": { "@types/json-schema": {
"version": "7.0.7", "version": "7.0.7",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
@ -210,6 +250,14 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true "dev": true
}, },
"@types/keyv": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz",
"integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==",
"requires": {
"@types/node": "*"
}
},
"@types/mime": { "@types/mime": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@ -219,8 +267,7 @@
"@types/node": { "@types/node": {
"version": "14.14.37", "version": "14.14.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
"integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==", "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw=="
"dev": true
}, },
"@types/qs": { "@types/qs": {
"version": "6.9.6", "version": "6.9.6",
@ -234,6 +281,14 @@
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
"dev": true "dev": true
}, },
"@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
"integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
"requires": {
"@types/node": "*"
}
},
"@types/serve-static": { "@types/serve-static": {
"version": "1.13.9", "version": "1.13.9",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz",
@ -244,6 +299,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz",
"integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==",
"dev": true
},
"@types/winston": { "@types/winston": {
"version": "2.4.4", "version": "2.4.4",
"resolved": "https://registry.npmjs.org/@types/winston/-/winston-2.4.4.tgz", "resolved": "https://registry.npmjs.org/@types/winston/-/winston-2.4.4.tgz",
@ -851,6 +912,12 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true
},
"atob": { "atob": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
@ -1192,6 +1259,35 @@
"unset-value": "^1.0.0" "unset-value": "^1.0.0"
} }
}, },
"cacheable-lookup": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="
},
"cacheable-request": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz",
"integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==",
"requires": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
},
"dependencies": {
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"requires": {
"pump": "^3.0.0"
}
}
}
},
"call-bind": { "call-bind": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@ -1356,6 +1452,14 @@
"wrap-ansi": "^5.1.0" "wrap-ansi": "^5.1.0"
} }
}, },
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
"integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
"requires": {
"mimic-response": "^1.0.0"
}
},
"collection-visit": { "collection-visit": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@ -1417,6 +1521,15 @@
"text-hex": "1.0.x" "text-hex": "1.0.x"
} }
}, },
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
},
"commander": { "commander": {
"version": "2.20.3", "version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@ -1649,12 +1762,32 @@
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"dev": true "dev": true
}, },
"decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"requires": {
"mimic-response": "^3.1.0"
},
"dependencies": {
"mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
}
}
},
"deep-is": { "deep-is": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true "dev": true
}, },
"defer-to-connect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="
},
"define-properties": { "define-properties": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@ -1705,6 +1838,12 @@
} }
} }
}, },
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
"depd": { "depd": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@ -1868,7 +2007,6 @@
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": { "requires": {
"once": "^1.4.0" "once": "^1.4.0"
} }
@ -2869,6 +3007,17 @@
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
"dev": true "dev": true
}, },
"form-data": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"fragment-cache": { "fragment-cache": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@ -3046,6 +3195,24 @@
} }
} }
}, },
"got": {
"version": "11.8.2",
"resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz",
"integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==",
"requires": {
"@sindresorhus/is": "^4.0.0",
"@szmarczak/http-timer": "^4.0.5",
"@types/cacheable-request": "^6.0.1",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^5.0.3",
"cacheable-request": "^7.0.1",
"decompress-response": "^6.0.0",
"http2-wrapper": "^1.0.0-beta.5.2",
"lowercase-keys": "^2.0.0",
"p-cancelable": "^2.0.0",
"responselike": "^2.0.0"
}
},
"graceful-fs": { "graceful-fs": {
"version": "4.2.3", "version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
@ -3151,6 +3318,11 @@
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true "dev": true
}, },
"http-cache-semantics": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
},
"http-errors": { "http-errors": {
"version": "1.7.3", "version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
@ -3163,6 +3335,15 @@
"toidentifier": "1.0.0" "toidentifier": "1.0.0"
} }
}, },
"http2-wrapper": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
"requires": {
"quick-lru": "^5.1.1",
"resolve-alpn": "^1.0.0"
}
},
"https-browserify": { "https-browserify": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
@ -3509,6 +3690,11 @@
"esprima": "^4.0.0" "esprima": "^4.0.0"
} }
}, },
"json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
},
"json-parse-better-errors": { "json-parse-better-errors": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@ -3536,6 +3722,14 @@
"minimist": "^1.2.0" "minimist": "^1.2.0"
} }
}, },
"keyv": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz",
"integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==",
"requires": {
"json-buffer": "3.0.1"
}
},
"kind-of": { "kind-of": {
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@ -3646,6 +3840,11 @@
} }
} }
}, },
"lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
},
"lru-cache": { "lru-cache": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@ -3800,6 +3999,11 @@
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true "dev": true
}, },
"mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
},
"minimalistic-assert": { "minimalistic-assert": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@ -3989,6 +4193,11 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"normalize-url": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.0.1.tgz",
"integrity": "sha512-VU4pzAuh7Kip71XEmO9aNREYAdMHFGTVj/i+CaTImS8x0i1d3jUZkXhqluy/PRgjPLMgsLQulYY3PJ/aSbSjpQ=="
},
"npm-run-all": { "npm-run-all": {
"version": "4.1.5", "version": "4.1.5",
"resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
@ -4177,7 +4386,6 @@
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -4222,6 +4430,11 @@
"mem": "^4.0.0" "mem": "^4.0.0"
} }
}, },
"p-cancelable": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="
},
"p-defer": { "p-defer": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
@ -4479,7 +4692,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": { "requires": {
"end-of-stream": "^1.1.0", "end-of-stream": "^1.1.0",
"once": "^1.3.1" "once": "^1.3.1"
@ -4537,6 +4749,11 @@
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true "dev": true
}, },
"quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="
},
"randombytes": { "randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -4721,6 +4938,11 @@
"path-parse": "^1.0.6" "path-parse": "^1.0.6"
} }
}, },
"resolve-alpn": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.1.2.tgz",
"integrity": "sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA=="
},
"resolve-cwd": { "resolve-cwd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
@ -4765,6 +4987,14 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true "dev": true
}, },
"responselike": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
"integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
"requires": {
"lowercase-keys": "^2.0.0"
}
},
"ret": { "ret": {
"version": "0.1.15", "version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
@ -6348,8 +6578,7 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"dev": true
}, },
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",

View File

@ -32,6 +32,7 @@
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"decache": "^4.6.0", "decache": "^4.6.0",
"express-http-proxy": "^1.6.2", "express-http-proxy": "^1.6.2",
"got": "^11.8.2",
"log-rotate": "^0.2.8" "log-rotate": "^0.2.8"
}, },
"devDependencies": { "devDependencies": {
@ -40,6 +41,7 @@
"@types/async": "^3.2.6", "@types/async": "^3.2.6",
"@types/express": "^4.17.11", "@types/express": "^4.17.11",
"@types/express-http-proxy": "^1.6.1", "@types/express-http-proxy": "^1.6.1",
"@types/got": "^9.6.11",
"@types/node": "^14.14.37", "@types/node": "^14.14.37",
"@types/winston": "^2.4.4", "@types/winston": "^2.4.4",
"@typescript-eslint/eslint-plugin": "^4.21.0", "@typescript-eslint/eslint-plugin": "^4.21.0",

View File

@ -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.

View File

@ -0,0 +1,56 @@
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);
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();
})
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;
};
});

View File

@ -96,6 +96,8 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
// TODO: add a settings to choose? // TODO: add a settings to choose?
config.useDefaultPersistent() config.useDefaultPersistent()
config.useListRoomsApi(apikey)
let logLevel: ProsodyLogLevel | undefined let logLevel: ProsodyLogLevel | undefined
if (logger.level && (typeof logger.level === 'string')) { if (logger.level && (typeof logger.level === 'string')) {
if (logger.level === 'error' || logger.level === 'info' || logger.level === 'debug') { if (logger.level === 'error' || logger.level === 'info' || logger.level === 'debug') {

View File

@ -236,6 +236,11 @@ class ProsodyConfigContent {
this.muc.set('muc_room_default_persistent', true) 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)
}
setLog (level: ProsodyLogLevel, syslog?: ProsodyLogLevel[]): void { setLog (level: ProsodyLogLevel, syslog?: ProsodyLogLevel[]): void {
let log = '' let log = ''
log += 'log = {\n' log += 'log = {\n'

View File

@ -1,5 +1,4 @@
import type { Router, Request, Response, NextFunction } from 'express' import type { Router, Request, Response, NextFunction } from 'express'
import type { ChatType, ProsodyListRoomsResult } from '../../../shared/lib/types'
import { diag } from '../diagnostic' import { diag } from '../diagnostic'
import { getBaseStaticRoute, isUserAdmin } from '../helpers' import { getBaseStaticRoute, isUserAdmin } from '../helpers'
import { asyncMiddleware } from '../middlewares/async' import { asyncMiddleware } from '../middlewares/async'
@ -40,38 +39,6 @@ async function initSettingsRouter (options: RegisterServerOptions): Promise<Rout
} }
)) ))
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
}
res.status(200)
const r: ProsodyListRoomsResult = {
ok: true,
rooms: [] // TODO: get room list from Prosody
}
res.json(r)
}
))
return router return router
} }

View File

@ -1,16 +1,19 @@
import type { Router, RequestHandler, Request, Response, NextFunction } from 'express' import type { Router, RequestHandler, Request, Response, NextFunction } from 'express'
import type { ProxyOptions } from 'express-http-proxy' import type { ProxyOptions } from 'express-http-proxy'
import type { ChatType } from '../../../shared/lib/types' import type { ChatType, ProsodyListRoomsResult } from '../../../shared/lib/types'
import { getBaseRouterRoute, getBaseStaticRoute } from '../helpers' import { getBaseRouterRoute, getBaseStaticRoute, isUserAdmin } from '../helpers'
import { asyncMiddleware } from '../middlewares/async' import { asyncMiddleware } from '../middlewares/async'
import { getProsodyDomain } from '../prosody/config/domain' import { getProsodyDomain } from '../prosody/config/domain'
import { getAPIKey } from '../apikey'
import * as path from 'path' import * as path from 'path'
const bodyParser = require('body-parser') const bodyParser = require('body-parser')
const got = require('got')
const fs = require('fs').promises const fs = require('fs').promises
const proxy = require('express-http-proxy') const proxy = require('express-http-proxy')
let httpBindRoute: RequestHandler let httpBindRoute: RequestHandler
let prosodyPort: string | undefined
async function initWebchatRouter (options: RegisterServerOptions): Promise<Router> { async function initWebchatRouter (options: RegisterServerOptions): Promise<Router> {
const { const {
@ -97,6 +100,54 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
httpBindRoute(req, res, next) 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 (!prosodyPort) {
throw new Error('It seems that prosody is not binded... Cant list rooms.')
}
// FIXME: can the api be on http://localhost instead of http://room.localhost?
const apiUrl = `http://room.localhost:${prosodyPort}/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)
},
responseType: 'json',
resolveBodyOnly: true
})
res.status(200)
const r: ProsodyListRoomsResult = {
ok: true,
rooms: rooms
}
res.json(r)
}
))
return router return router
} }
@ -108,6 +159,7 @@ function changeHttpBindRoute ({ peertubeHelpers }: RegisterServerOptions, port:
port = null port = null
} }
if (port === null) { if (port === null) {
prosodyPort = undefined
httpBindRoute = (_req: Request, res: Response, _next: NextFunction) => { httpBindRoute = (_req: Request, res: Response, _next: NextFunction) => {
res.status(404) res.status(404)
res.send('Not found') res.send('Not found')
@ -122,6 +174,7 @@ function changeHttpBindRoute ({ peertubeHelpers }: RegisterServerOptions, port:
parseReqBody: true // Note that setting this to false overrides reqAsBuffer and reqBodyEncoding below. parseReqBody: true // Note that setting this to false overrides reqAsBuffer and reqBodyEncoding below.
// FIXME: should we remove cookies? // FIXME: should we remove cookies?
} }
prosodyPort = port
httpBindRoute = proxy('http://localhost:' + port, options) httpBindRoute = proxy('http://localhost:' + port, options)
} }
} }

View File

@ -8,8 +8,11 @@ interface ProsodyListRoomsResultError {
interface ProsodyListRoomsResultSuccess { interface ProsodyListRoomsResultSuccess {
ok: true ok: true
rooms: Array<{ rooms: Array<{
jid: string
localpart: string
name: string name: string
href: string lang: string
description: string
}> }>
} }