Remove twitter whitelisted option

It doesn't seem to be required
pull/6266/head
Chocobozzz 2024-03-08 10:49:08 +01:00
parent 54a7183b11
commit 10e78bb778
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
17 changed files with 92 additions and 205 deletions

View File

@ -671,10 +671,10 @@
<div class="pt-two-cols mt-4"> <!-- Twitter grid --> <div class="pt-two-cols mt-4"> <!-- Twitter grid -->
<div class="title-col"> <div class="title-col">
<h2 i18n>TWITTER</h2> <h2 i18n>TWITTER/X</h2>
<div i18n class="inner-form-description"> <div i18n class="inner-form-description">
Provide the Twitter account representing your instance to improve link previews. Extra configuration required by Twitter/X. All other social media (Facebook, Mastodon, etc.) are supported out of the box.
If you don't have a Twitter account, just leave the default value.
</div> </div>
</div> </div>
@ -684,7 +684,13 @@
<ng-container formGroupName="twitter"> <ng-container formGroupName="twitter">
<div class="form-group"> <div class="form-group">
<label for="servicesTwitterUsername" i18n>Your Twitter username</label> <label for="servicesTwitterUsername" i18n>Your Twitter/X username</label>
<div class="label-small-info">
<p class="mb-0">Indicates the Twitter/X account for the website or platform where the content was published.</p>
<p>This is just an extra information injected in PeerTube HTML that is required by Twitter/X. If you don't have a Twitter/X account, just leave the default value.</p>
</div>
<input <input
type="text" id="servicesTwitterUsername" class="form-control" type="text" id="servicesTwitterUsername" class="form-control"
@ -694,29 +700,6 @@
<div *ngIf="formErrors.services.twitter.username" class="form-error" role="alert">{{ formErrors.services.twitter.username }}</div> <div *ngIf="formErrors.services.twitter.username" class="form-error" role="alert">{{ formErrors.services.twitter.username }}</div>
</div> </div>
<div class="form-group">
<my-peertube-checkbox inputName="servicesTwitterWhitelisted" formControlName="whitelisted">
<ng-template ptTemplate="label">
<ng-container i18n>Instance allowed by Twitter/X</ng-container>
</ng-template>
<ng-template ptTemplate="help">
<ng-container i18n>
<p class="mb-2">
If your instance is explicitly allowed by Twitter/X, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
If the instance is not, we use an image link card that will redirect to your PeerTube instance.
</p>
<p>
Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/w/blabla) on
<a class="link-orange" target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a>
to see if you instance is allowed.
</p>
</ng-container>
</ng-template>
</my-peertube-checkbox>
</div>
</ng-container> </ng-container>
</ng-container> </ng-container>

View File

@ -131,8 +131,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
}, },
services: { services: {
twitter: { twitter: {
username: SERVICES_TWITTER_USERNAME_VALIDATOR, username: SERVICES_TWITTER_USERNAME_VALIDATOR
whitelisted: null
} }
}, },
client: { client: {

View File

@ -841,13 +841,12 @@ instance:
Expires: 2025-12-31T11:00:00.000Z' Expires: 2025-12-31T11:00:00.000Z'
services: services:
# Cards configuration to format video in Twitter # Cards configuration to format video in Twitter/X
# All other social media (Facebook, Mastodon, etc.) are supported out of the box
twitter: twitter:
username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published # Indicates the Twitter account for the website or platform where the content was published
# If true, a video player will be embedded in the Twitter feed on PeerTube video share # This is just an information injected in HTML that is required by Twitter/X
# If false, we use an image link card that will redirect on your PeerTube instance username: '@Chocobozzz'
# Change it to `true`, and then test on https://cards-dev.twitter.com/validator to see if you are whitelisted
whitelisted: false
followers: followers:
instance: instance:

View File

@ -851,13 +851,12 @@ instance:
Expires: 2025-12-31T11:00:00.000Z' Expires: 2025-12-31T11:00:00.000Z'
services: services:
# Cards configuration to format video in Twitter # Cards configuration to format video in Twitter/X
# All other social media (Facebook, Mastodon, etc.) are supported out of the box
twitter: twitter:
username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published # Indicates the Twitter/X account for the website or platform where the content was published
# If true, a video player will be embedded in the Twitter feed on PeerTube video share # This is just an information injected in HTML that is required by Twitter/X
# If false, we use an image link card that will redirect on your PeerTube instance username: '@Chocobozzz'
# Change it to `true`, and then test on https://cards-dev.twitter.com/validator to see if you are whitelisted
whitelisted: false
followers: followers:
instance: instance:

View File

@ -48,7 +48,6 @@ export interface CustomConfig {
services: { services: {
twitter: { twitter: {
username: string username: string
whitelisted: boolean
} }
} }

View File

@ -503,8 +503,7 @@ export class ConfigCommand extends AbstractCommand {
}, },
services: { services: {
twitter: { twitter: {
username: '@MySuperUsername', username: '@MySuperUsername'
whitelisted: true
} }
}, },
client: { client: {

View File

@ -52,8 +52,7 @@ describe('Test config API validators', function () {
}, },
services: { services: {
twitter: { twitter: {
username: '@MySuperUsername', username: '@MySuperUsername'
whitelisted: true
} }
}, },
client: { client: {

View File

@ -42,7 +42,6 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
expect(data.instance.customizations.javascript).to.be.empty expect(data.instance.customizations.javascript).to.be.empty
expect(data.services.twitter.username).to.equal('@Chocobozzz') expect(data.services.twitter.username).to.equal('@Chocobozzz')
expect(data.services.twitter.whitelisted).to.be.false
expect(data.client.videos.miniature.preferAuthorDisplayName).to.be.false expect(data.client.videos.miniature.preferAuthorDisplayName).to.be.false
expect(data.client.menu.login.redirectOnSingleExternalAuth).to.be.false expect(data.client.menu.login.redirectOnSingleExternalAuth).to.be.false
@ -161,7 +160,6 @@ function checkUpdatedConfig (data: CustomConfig) {
expect(data.instance.customizations.css).to.equal('body { background-color: red; }') expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
expect(data.services.twitter.username).to.equal('@Kuja') expect(data.services.twitter.username).to.equal('@Kuja')
expect(data.services.twitter.whitelisted).to.be.true
expect(data.client.videos.miniature.preferAuthorDisplayName).to.be.true expect(data.client.videos.miniature.preferAuthorDisplayName).to.be.true
expect(data.client.menu.login.redirectOnSingleExternalAuth).to.be.true expect(data.client.menu.login.redirectOnSingleExternalAuth).to.be.true
@ -291,8 +289,7 @@ const newCustomConfig: CustomConfig = {
}, },
services: { services: {
twitter: { twitter: {
username: '@Kuja', username: '@Kuja'
whitelisted: true
} }
}, },
client: { client: {

View File

@ -120,148 +120,73 @@ describe('Test Open Graph and Twitter cards HTML tags', function () {
describe('Twitter card', async function () { describe('Twitter card', async function () {
describe('Not whitelisted', function () { before(async function () {
const config = await servers[0].config.getCustomConfig()
async function accountPageTest (path: string) { config.services.twitter = {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 }) username: '@Kuja'
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="summary" />')
expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
expect(text).to.contain(`<meta property="twitter:title" content="${account.name}" />`)
expect(text).to.contain(`<meta property="twitter:description" content="${account.description}" />`)
} }
async function channelPageTest (path: string) { await servers[0].config.updateCustomConfig({ newCustomConfig: config })
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="summary" />')
expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
expect(text).to.contain(`<meta property="twitter:title" content="${servers[0].store.channel.displayName}" />`)
expect(text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`)
}
async function watchVideoPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="summary_large_image" />')
expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
expect(text).to.contain(`<meta property="twitter:title" content="${videoName}" />`)
expect(text).to.contain(`<meta property="twitter:description" content="${videoDescriptionPlainText}" />`)
}
async function watchPlaylistPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="summary" />')
expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
expect(text).to.contain(`<meta property="twitter:title" content="${playlistName}" />`)
expect(text).to.contain(`<meta property="twitter:description" content="${playlistDescription}" />`)
}
it('Should have valid twitter card on the watch video page', async function () {
for (const path of getWatchVideoBasePaths()) {
for (const id of videoIds) {
await watchVideoPageTest(path + id)
}
}
})
it('Should have valid twitter card on the watch playlist page', async function () {
for (const path of getWatchPlaylistBasePaths()) {
for (const id of playlistIds) {
await watchPlaylistPageTest(path + id)
}
}
})
it('Should have valid twitter card on the account page', async function () {
await accountPageTest('/accounts/' + account.name)
await accountPageTest('/a/' + account.name)
await accountPageTest('/@' + account.name)
})
it('Should have valid twitter card on the channel page', async function () {
await channelPageTest('/video-channels/' + servers[0].store.channel.name)
await channelPageTest('/c/' + servers[0].store.channel.name)
await channelPageTest('/@' + servers[0].store.channel.name)
})
}) })
describe('Whitelisted', function () { async function accountPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
before(async function () { expect(text).to.contain('<meta property="twitter:card" content="summary" />')
const config = await servers[0].config.getCustomConfig() expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
config.services.twitter = { }
username: '@Kuja',
whitelisted: true async function channelPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="summary" />')
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
}
async function watchVideoPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="player" />')
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
}
async function watchPlaylistPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="player" />')
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
}
it('Should have valid twitter card on the watch video page', async function () {
for (const path of getWatchVideoBasePaths()) {
for (const id of videoIds) {
await watchVideoPageTest(path + id)
} }
await servers[0].config.updateCustomConfig({ newCustomConfig: config })
})
async function accountPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="summary" />')
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
} }
})
async function channelPageTest (path: string) { it('Should have valid twitter card on the watch playlist page', async function () {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 }) for (const path of getWatchPlaylistBasePaths()) {
const text = res.text for (const id of playlistIds) {
await watchPlaylistPageTest(path + id)
expect(text).to.contain('<meta property="twitter:card" content="summary" />')
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
}
async function watchVideoPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="player" />')
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
}
async function watchPlaylistPageTest (path: string) {
const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
const text = res.text
expect(text).to.contain('<meta property="twitter:card" content="player" />')
expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
}
it('Should have valid twitter card on the watch video page', async function () {
for (const path of getWatchVideoBasePaths()) {
for (const id of videoIds) {
await watchVideoPageTest(path + id)
}
} }
}) }
})
it('Should have valid twitter card on the watch playlist page', async function () { it('Should have valid twitter card on the account page', async function () {
for (const path of getWatchPlaylistBasePaths()) { await accountPageTest('/accounts/' + account.name)
for (const id of playlistIds) { await accountPageTest('/a/' + account.name)
await watchPlaylistPageTest(path + id) await accountPageTest('/@' + account.name)
} })
}
})
it('Should have valid twitter card on the account page', async function () { it('Should have valid twitter card on the channel page', async function () {
await accountPageTest('/accounts/' + account.name) await channelPageTest('/video-channels/' + servers[0].store.channel.name)
await accountPageTest('/a/' + account.name) await channelPageTest('/c/' + servers[0].store.channel.name)
await accountPageTest('/@' + account.name) await channelPageTest('/@' + servers[0].store.channel.name)
})
it('Should have valid twitter card on the channel page', async function () {
await channelPageTest('/video-channels/' + servers[0].store.channel.name)
await channelPageTest('/c/' + servers[0].store.channel.name)
await channelPageTest('/@' + servers[0].store.channel.name)
})
}) })
}) })

View File

@ -263,8 +263,7 @@ function customConfig (): CustomConfig {
}, },
services: { services: {
twitter: { twitter: {
username: CONFIG.SERVICES.TWITTER.USERNAME, username: CONFIG.SERVICES.TWITTER.USERNAME
whitelisted: CONFIG.SERVICES.TWITTER.WHITELISTED
} }
}, },
client: { client: {

View File

@ -243,7 +243,6 @@ const customConfigKeysToKeep = new Set([
'instance-customizations-javascript', 'instance-customizations-javascript',
'instance-customizations-css', 'instance-customizations-css',
'services-twitter-username', 'services-twitter-username',
'services-twitter-whitelisted',
'cache-previews-size', 'cache-previews-size',
'cache-captions-size', 'cache-captions-size',
'signup-enabled', 'signup-enabled',

View File

@ -51,7 +51,7 @@ function checkMissedConfig () {
'defaults.publish.download_enabled', 'defaults.publish.comments_enabled', 'defaults.publish.privacy', 'defaults.publish.licence', 'defaults.publish.download_enabled', 'defaults.publish.comments_enabled', 'defaults.publish.privacy', 'defaults.publish.licence',
'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route', 'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route',
'instance.is_nsfw', 'instance.default_nsfw_policy', 'instance.robots', 'instance.securitytxt', 'instance.is_nsfw', 'instance.default_nsfw_policy', 'instance.robots', 'instance.securitytxt',
'services.twitter.username', 'services.twitter.whitelisted', 'services.twitter.username',
'followers.instance.enabled', 'followers.instance.manual_approval', 'followers.instance.enabled', 'followers.instance.manual_approval',
'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces', 'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces',
'history.videos.max_age', 'views.videos.remote.max_age', 'views.videos.local_buffer_update_interval', 'views.videos.ip_view_expiration', 'history.videos.max_age', 'views.videos.remote.max_age', 'views.videos.local_buffer_update_interval', 'views.videos.ip_view_expiration',

View File

@ -596,8 +596,7 @@ const CONFIG = {
}, },
SERVICES: { SERVICES: {
TWITTER: { TWITTER: {
get USERNAME () { return config.get<string>('services.twitter.username') }, get USERNAME () { return config.get<string>('services.twitter.username') }
get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') }
} }
}, },
FOLLOWERS: { FOLLOWERS: {

View File

@ -87,12 +87,9 @@ export class PlaylistHtml {
const list = { numberOfItems: playlist.get('videosLength') as number } const list = { numberOfItems: playlist.get('videosLength') as number }
const schemaType = 'ItemList' const schemaType = 'ItemList'
let twitterCard: 'player' | 'summary' const twitterCard = addTwitterCard
if (addTwitterCard) { ? 'player'
twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED : undefined
? 'player'
: 'summary'
}
const ogType = addOG const ogType = addOG
? 'video' as 'video' ? 'video' as 'video'

View File

@ -1,6 +1,7 @@
import { escapeHTML } from '@peertube/peertube-core-utils' import { escapeHTML } from '@peertube/peertube-core-utils'
import { HttpStatusCode, VideoPrivacy } from '@peertube/peertube-models' import { HttpStatusCode, VideoPrivacy } from '@peertube/peertube-models'
import { toCompleteUUID } from '@server/helpers/custom-validators/misc.js' import { toCompleteUUID } from '@server/helpers/custom-validators/misc.js'
import { Memoize } from '@server/helpers/memoize.js'
import express from 'express' import express from 'express'
import validator from 'validator' import validator from 'validator'
import { CONFIG } from '../../../initializers/config.js' import { CONFIG } from '../../../initializers/config.js'
@ -9,10 +10,9 @@ import { VideoModel } from '../../../models/video/video.js'
import { MVideo, MVideoThumbnailBlacklist } from '../../../types/models/index.js' import { MVideo, MVideoThumbnailBlacklist } from '../../../types/models/index.js'
import { getActivityStreamDuration } from '../../activitypub/activity.js' import { getActivityStreamDuration } from '../../activitypub/activity.js'
import { isVideoInPrivateDirectory } from '../../video-privacy.js' import { isVideoInPrivateDirectory } from '../../video-privacy.js'
import { Memoize } from '@server/helpers/memoize.js'
import { TagsHtml } from './tags-html.js'
import { PageHtml } from './page-html.js'
import { CommonEmbedHtml } from './common-embed-html.js' import { CommonEmbedHtml } from './common-embed-html.js'
import { PageHtml } from './page-html.js'
import { TagsHtml } from './tags-html.js'
export class VideoHtml { export class VideoHtml {
@ -99,12 +99,9 @@ export class VideoHtml {
? 'video' as 'video' ? 'video' as 'video'
: undefined : undefined
let twitterCard: 'player' | 'summary_large_image' const twitterCard = addTwitterCard
if (addTwitterCard) { ? 'player'
twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED : undefined
? 'player'
: 'summary_large_image'
}
const schemaType = 'VideoObject' const schemaType = 'VideoObject'

View File

@ -19,7 +19,6 @@ const customConfigUpdateValidator = [
body('instance.customizations.javascript').exists(), body('instance.customizations.javascript').exists(),
body('services.twitter.username').exists(), body('services.twitter.username').exists(),
body('services.twitter.whitelisted').isBoolean(),
body('cache.previews.size').isInt(), body('cache.previews.size').isInt(),
body('cache.captions.size').isInt(), body('cache.captions.size').isInt(),

View File

@ -8743,8 +8743,6 @@ components:
properties: properties:
username: username:
type: string type: string
whitelisted:
type: boolean
cache: cache:
type: object type: object
properties: properties: