146 lines
6.2 KiB
JavaScript
146 lines
6.2 KiB
JavaScript
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
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 {
|
|
external_auth_oidc_alert_message: { type: String, attribute: false },
|
|
remote_peertube_state: { type: String, attribute: false },
|
|
remote_peertube_alert_message: { type: String, attribute: false },
|
|
remote_peertube_try_anyway_url: { type: String, attribute: false },
|
|
remote_peertube_open_failed_url: { type: String, attribute: false }
|
|
}
|
|
}
|
|
|
|
constructor () {
|
|
super()
|
|
this.remote_peertube_state = 'init'
|
|
}
|
|
|
|
render () {
|
|
return tplExternalLoginModal(this, {
|
|
external_auth_oidc_alert_message: this.external_auth_oidc_alert_message,
|
|
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,
|
|
remote_peertube_open_failed_url: this.remote_peertube_open_failed_url
|
|
})
|
|
}
|
|
|
|
onRemotePeertubeKeyUp (_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 = null // 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'
|
|
const url = new URL(
|
|
'/videos/watch/' + encodeURIComponent(videos.data[0].uuid), remotePeertubeUrl
|
|
).toString()
|
|
this.openUrlTargetTop(url)
|
|
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)
|
|
}
|
|
}
|
|
|
|
openUrlTargetTop (url) {
|
|
try {
|
|
// window.open can fail when in an iframe that restricts some operations
|
|
// (when embeding the chat in a website).
|
|
// So, we must try/catch, and propose an alternative open method.
|
|
window.open(url, '_top')
|
|
} catch (e) {
|
|
console.log(e)
|
|
this.remote_peertube_state = 'error'
|
|
// eslint-disable-next-line no-undef
|
|
this.remote_peertube_alert_message = __(LOC_login_remote_peertube_video_open_failed)
|
|
this.remote_peertube_open_failed_url = url
|
|
|
|
this.remote_peertube_try_anyway_url = ''
|
|
}
|
|
}
|
|
|
|
clearAlert () {
|
|
this.external_auth_oidc_alert_message = ''
|
|
this.remote_peertube_alert_message = ''
|
|
this.remote_peertube_try_anyway_url = ''
|
|
this.remote_peertube_open_failed_url = ''
|
|
}
|
|
}
|
|
|
|
api.elements.define('converse-livechat-external-login-content', LivechatExternalLoginContentElement)
|