Log in with external Peertube account (#348):
* For anonymous users: new "log in using an external account" dialog, with the "remote Peertube account" options * ConverseJS: using global vars for custom localized string (injected using Webpack)
This commit is contained in:
117
conversejs/custom/livechat-external-login-content.js
Normal file
117
conversejs/custom/livechat-external-login-content.js
Normal file
@ -0,0 +1,117 @@
|
||||
import { api } from '@converse/headless/core.js'
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { tplExternalLoginModal } from 'templates/livechat-external-login-modal.js'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
export default class LivechatExternalLoginContentElement extends CustomElement {
|
||||
static get properties () {
|
||||
return {
|
||||
remote_peertube_state: { type: String, attribute: false },
|
||||
remote_peertube_alert_message: { type: String, attribute: false },
|
||||
remote_peertube_try_anyway_url: { type: String, attribute: false }
|
||||
}
|
||||
}
|
||||
|
||||
constructor () {
|
||||
super()
|
||||
this.remote_peertube_state = 'init'
|
||||
}
|
||||
|
||||
render () {
|
||||
return tplExternalLoginModal(this, {
|
||||
remote_peertube_state: this.remote_peertube_state,
|
||||
remote_peertube_alert_message: this.remote_peertube_alert_message,
|
||||
remote_peertube_try_anyway_url: this.remote_peertube_try_anyway_url
|
||||
})
|
||||
}
|
||||
|
||||
onKeyUp (_ev) {
|
||||
if (this.remote_peertube_state !== 'init') {
|
||||
this.remote_peertube_state = 'init'
|
||||
this.remote_peertube_alert_message = ''
|
||||
this.clearAlert()
|
||||
}
|
||||
}
|
||||
|
||||
async openRemotePeertube (ev) {
|
||||
ev.preventDefault()
|
||||
this.clearAlert()
|
||||
|
||||
const remotePeertubeUrl = ev.target.peertube_url.value.trim()
|
||||
if (!remotePeertubeUrl) { return }
|
||||
|
||||
this.remote_peertube_state = 'loading'
|
||||
|
||||
try {
|
||||
// Calling Peertube API to check if livechat plugin is available.
|
||||
// In the meantime, this will also check that the URL exists, and is a Peertube instance
|
||||
// (or something with similar API result... as the user typed the url, we assume there is no security risk here).
|
||||
const configApiUrl = new URL('/api/v1/config', remotePeertubeUrl)
|
||||
const config = await (await fetch(configApiUrl.toString())).json()
|
||||
if (!config || typeof config !== 'object') {
|
||||
throw new Error('Invalid config API result')
|
||||
}
|
||||
if (!('plugin' in config) || !('registered' in config.plugin) || !Array.isArray(config.plugin.registered)) {
|
||||
throw new Error('No registered plugin in config API result')
|
||||
}
|
||||
if (!config.plugin.registered.find(p => p.npmName === 'peertube-plugin-livechat')) {
|
||||
console.error('Plugin livechat not available on remote instance')
|
||||
this.remote_peertube_state = 'error'
|
||||
// eslint-disable-next-line no-undef
|
||||
this.remote_peertube_alert_message = __(LOC_login_remote_peertube_no_livechat)
|
||||
return
|
||||
}
|
||||
// Note: we do not check if the livechat plugin disables federation (neither on current or remote instance).
|
||||
// We assume this is not a standard use case, and we don't want to add to much use cases.
|
||||
|
||||
// Now we must search the current video on the remote instance, to be sure it federates, and to get the url.
|
||||
// Note: url search can be disabled on remote instance for non logged in users...
|
||||
// As we are not authenticated on remote here, there are chances that the search wont return anything.
|
||||
// As a fallback, we will launch another search with the video UUID.
|
||||
// And if no result neither, we will just propose to open using the lazy-load page.
|
||||
const videoUrl = api.settings.get('livechat_peertube_video_original_url')
|
||||
const videoUUID = api.settings.get('livechat_peertube_video_uuid')
|
||||
for (const search of [videoUrl, videoUUID]) {
|
||||
if (!search) { continue }
|
||||
// searching first on federation network, then on vidiverse (this could be disabled)
|
||||
for (const searchTarget of ['local', 'search-index']) {
|
||||
const searchAPIUrl = new URL('/api/v1/search/videos', remotePeertubeUrl)
|
||||
searchAPIUrl.searchParams.append('start', '0')
|
||||
searchAPIUrl.searchParams.append('count', 1)
|
||||
searchAPIUrl.searchParams.append('search', search)
|
||||
searchAPIUrl.searchParams.append('searchTarget', searchTarget)
|
||||
const videos = await (await fetch(searchAPIUrl.toString())).json()
|
||||
if (videos && Array.isArray(videos.data) && videos.data.length > 0 && videos.data[0].uuid) {
|
||||
console.log('Video found, opening on remote instance')
|
||||
this.remote_peertube_state = 'ok'
|
||||
window.location.href = new URL(
|
||||
'/videos/watch/' + encodeURIComponent(videos.data[0].uuid), remotePeertubeUrl
|
||||
).toString()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.error('Video not found on remote instance')
|
||||
this.remote_peertube_state = 'error'
|
||||
// eslint-disable-next-line no-undef
|
||||
this.remote_peertube_alert_message = __(LOC_login_remote_peertube_video_not_found)
|
||||
this.remote_peertube_try_anyway_url = new URL(
|
||||
'/search/lazy-load-video;url=' + encodeURIComponent(videoUrl),
|
||||
remotePeertubeUrl
|
||||
).toString()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
this.remote_peertube_state = 'error'
|
||||
// eslint-disable-next-line no-undef
|
||||
this.remote_peertube_alert_message = __(LOC_login_remote_peertube_url_invalid)
|
||||
}
|
||||
}
|
||||
|
||||
clearAlert () {
|
||||
this.remote_peertube_alert_message = ''
|
||||
this.remote_peertube_try_anyway_url = ''
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('converse-livechat-external-login-content', LivechatExternalLoginContentElement)
|
Reference in New Issue
Block a user