diff --git a/client/common/lib/contexts/peertube.ts b/client/common/lib/contexts/peertube.ts
index 0dac9914..61c4d34d 100644
--- a/client/common/lib/contexts/peertube.ts
+++ b/client/common/lib/contexts/peertube.ts
@@ -18,6 +18,7 @@ export type LiveChatSettings = SettingEntries & {
'prosody-room-allow-s2s': boolean
'converse-theme': ConverseJSTheme
'prosody-room-type': string
+ 'livechat-token-disabled': boolean
}
export class PtContext {
diff --git a/client/common/videowatch/elements/share-chat.ts b/client/common/videowatch/elements/share-chat.ts
index 88c8aa88..cb9a3ff1 100644
--- a/client/common/videowatch/elements/share-chat.ts
+++ b/client/common/videowatch/elements/share-chat.ts
@@ -111,7 +111,12 @@ export class ShareChatElement extends LivechatElement {
// Note: for dockEnabled, we check:
// * that the user is logged in
// * that the video is local (for remote video, tests case are too complicated, and it's not the main use case, so…)
- this.dockEnabled = !isAnonymousUser(this.ptContext.ptOptions) && this._video.isLocal
+ // * settings is not disabled
+ this.dockEnabled = (
+ !isAnonymousUser(this.ptContext.ptOptions) &&
+ this._video.isLocal &&
+ !settings['livechat-token-disabled']
+ )
this.autocolorsAvailable = isAutoColorsAvailable(settings['converse-theme'])
this._restorePreviousState()
diff --git a/languages/en.yml b/languages/en.yml
index 9f99fdbb..36b41eea 100644
--- a/languages/en.yml
+++ b/languages/en.yml
@@ -536,3 +536,11 @@ token_action_create: Create a new token
token_action_revoke: Revoke the token
token_default_label: Token generated from the web interface
token_action_revoke_confirm: Are you sure you want to revoke this token?
+auth_description: |
+
Authentication
+livechat_token_disabled_label: 'Disable livechat tokens'
+livechat_token_disabled_description: |
+ Users can generate long term tokens to connect to the chat.
+ These tokens can for example be used to include the chat in OBS web docks.
+ Check the documentation for more information.
+ You can disable this feature by checking this setting.
diff --git a/server/lib/prosody/auth.ts b/server/lib/prosody/auth.ts
index 674d281a..98636228 100644
--- a/server/lib/prosody/auth.ts
+++ b/server/lib/prosody/auth.ts
@@ -63,6 +63,7 @@ let singleton: LivechatProsodyAuth | undefined
export class LivechatProsodyAuth {
private readonly _options: RegisterServerOptions
private readonly _prosodyDomain: string
+ private _userTokensEnabled: boolean
private readonly _tokensPath: string
private readonly _passwords: Map = new Map()
private readonly _tokensInfoByJID: Map = new Map()
@@ -80,9 +81,10 @@ export class LivechatProsodyAuth {
outputEncoding: 'hex' as Encoding
}
- constructor (options: RegisterServerOptions, prosodyDomain: string, secretKey: string) {
+ constructor (options: RegisterServerOptions, prosodyDomain: string, userTokensEnabled: boolean, secretKey: string) {
this._options = options
this._prosodyDomain = prosodyDomain
+ this._userTokensEnabled = userTokensEnabled
this._secretKey = secretKey
this._tokensPath = path.join(
options.peertubeHelpers.plugin.getDataDirectoryPath(),
@@ -131,18 +133,20 @@ export class LivechatProsodyAuth {
if (entry) {
return true
}
- try {
- const tokensInfo = await this._getTokensInfoForJID(normalizedUsername + '@' + this._prosodyDomain)
- if (!tokensInfo || !tokensInfo.tokens.length) {
+ if (this._userTokensEnabled) {
+ try {
+ const tokensInfo = await this._getTokensInfoForJID(normalizedUsername + '@' + this._prosodyDomain)
+ if (!tokensInfo || !tokensInfo.tokens.length) {
+ return false
+ }
+ // Checking that the user is valid:
+ if (await this._userIdValid(tokensInfo.userId)) {
+ return true
+ }
+ } catch (err) {
+ this._logger.error(err as string)
return false
}
- // Checking that the user is valid:
- if (await this._userIdValid(tokensInfo.userId)) {
- return true
- }
- } catch (err) {
- this._logger.error(err as string)
- return false
}
return false
}
@@ -152,23 +156,25 @@ export class LivechatProsodyAuth {
if (entry && entry.password === password) {
return true
}
- try {
- const tokensInfo = await this._getTokensInfoForJID(normalizedUsername + '@' + this._prosodyDomain)
- if (!tokensInfo || !tokensInfo.tokens.length) {
- return false
- }
- // Checking that the user is valid:
- if (!await this._userIdValid(tokensInfo.userId)) {
- return false
- }
+ if (this._userTokensEnabled) {
+ try {
+ const tokensInfo = await this._getTokensInfoForJID(normalizedUsername + '@' + this._prosodyDomain)
+ if (!tokensInfo || !tokensInfo.tokens.length) {
+ return false
+ }
+ // Checking that the user is valid:
+ if (!await this._userIdValid(tokensInfo.userId)) {
+ return false
+ }
- // Is the password in tokens?
- if (tokensInfo.tokens.find((t) => t.password === password)) {
- return true
+ // Is the password in tokens?
+ if (tokensInfo.tokens.find((t) => t.password === password)) {
+ return true
+ }
+ } catch (err) {
+ this._logger.error(err as string)
+ return false
}
- } catch (err) {
- this._logger.error(err as string)
- return false
}
return false
}
@@ -179,6 +185,9 @@ export class LivechatProsodyAuth {
* @param user the user
*/
public async getUserTokens (user: MUserDefault): Promise {
+ if (!this._userTokensEnabled) {
+ return undefined
+ }
if (!user || !user.id) {
return undefined
}
@@ -210,7 +219,22 @@ export class LivechatProsodyAuth {
return tokens
}
+ /**
+ * Enable or disable user tokens. Must be called when the settings change.
+ * @param enabled
+ */
+ public setUserTokensEnabled (enabled: boolean): void {
+ this._userTokensEnabled = !!enabled
+ if (!this.userRegistered) {
+ // Empty the cache:
+ this._tokensInfoByJID.clear()
+ }
+ }
+
public async createUserToken (user: MUserDefault, label: string): Promise {
+ if (!this._userTokensEnabled) {
+ return undefined
+ }
if (!user || !user.id) {
return undefined
}
@@ -230,6 +254,9 @@ export class LivechatProsodyAuth {
}
public async revokeUserToken (user: MUserDefault, id: number): Promise {
+ if (!this._userTokensEnabled) {
+ return false
+ }
if (!user || !user.id) {
return false
}
@@ -448,12 +475,13 @@ export class LivechatProsodyAuth {
await options.storageManager.storeData('livechat-prosody-auth-secretkey', secretKey)
}
- singleton = new LivechatProsodyAuth(options, prosodyDomain, secretKey)
+ const userTokenDisabled = await options.settingsManager.getSetting('livechat-token-disabled')
+
+ singleton = new LivechatProsodyAuth(options, prosodyDomain, !userTokenDisabled, secretKey)
return singleton
}
public static async destroySingleton (): Promise {
- // TODO: sync to disk
singleton = undefined
}
}
diff --git a/server/lib/settings.ts b/server/lib/settings.ts
index eda78e1d..c51a3a62 100644
--- a/server/lib/settings.ts
+++ b/server/lib/settings.ts
@@ -9,6 +9,7 @@ import { RoomChannel } from './room-channel'
import { BotsCtl } from './bots/ctl'
import { ExternalAuthOIDC, ExternalAuthOIDCType } from './external-auth/oidc'
import { Emojis } from './emojis'
+import { LivechatProsodyAuth } from './prosody/auth'
import { loc } from './loc'
const escapeHTML = require('escape-html')
@@ -21,6 +22,7 @@ async function initSettings (options: RegisterServerOptions): Promise {
initImportantNotesSettings(options)
initChatSettings(options)
initFederationSettings(options)
+ initAuth(options)
initExternalAuth(options)
initAdvancedChannelCustomizationSettings(options)
initChatBehaviourSettings(options)
@@ -73,6 +75,8 @@ async function initSettings (options: RegisterServerOptions): Promise {
await Emojis.destroySingleton()
await Emojis.initSingleton(options)
+ LivechatProsodyAuth.singleton().setUserTokensEnabled(!settings['livechat-token-disabled'])
+
peertubeHelpers.logger.info('Saving settings, ensuring prosody is running')
await ensureProsodyRunning(options)
@@ -181,6 +185,35 @@ function initFederationSettings ({ registerSetting }: RegisterServerOptions): vo
})
}
+/**
+ * Initialize settings related to authentication.
+ * @param options peertube server options
+ */
+function initAuth (options: RegisterServerOptions): void {
+ const registerSetting = options.registerSetting
+
+ registerSetting({
+ type: 'html',
+ private: true,
+ descriptionHTML: loc('auth_description')
+ })
+
+ registerSetting({
+ type: 'html',
+ private: true,
+ descriptionHTML: loc('experimental_warning')
+ })
+
+ registerSetting({
+ name: 'livechat-token-disabled',
+ label: loc('livechat_token_disabled_label'),
+ descriptionHTML: loc('livechat_token_disabled_description'),
+ type: 'input-checkbox',
+ default: false,
+ private: false
+ })
+}
+
/**
* Registers settings related to the "External Authentication" section.
* @param param0 server options
diff --git a/server/main.ts b/server/main.ts
index e3854f26..61ae90ac 100644
--- a/server/main.ts
+++ b/server/main.ts
@@ -52,7 +52,7 @@ async function register (options: RegisterServerOptions): Promise {
await initSettings(options)
await Emojis.initSingleton(options) // after settings, before routes
- await LivechatProsodyAuth.initSingleton(options)
+ await LivechatProsodyAuth.initSingleton(options) // after settings, before routes
await initCustomFields(options)
await initRouters(options)
diff --git a/support/documentation/content/en/documentation/admin/settings.md b/support/documentation/content/en/documentation/admin/settings.md
index 39d97e57..31b58387 100644
--- a/support/documentation/content/en/documentation/admin/settings.md
+++ b/support/documentation/content/en/documentation/admin/settings.md
@@ -24,6 +24,12 @@ Following settings concern the federation with other Peertube instances, and oth
{{% livechat_label federation_dont_publish_remotely_description %}}
+## Authentication
+
+### {{% livechat_label livechat_token_disabled_label %}}
+
+In case you have any trouble with the long term authentication tokens, you can disable the feature here.
+
## External Authentication
See the detailed documentation page: