mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-05 10:49:28 +02:00
Add public links to AP representation
See https://github.com/Chocobozzz/PeerTube/issues/6389
This commit is contained in:
parent
de5adc09b2
commit
e81b6eba74
17 changed files with 267 additions and 152 deletions
|
@ -1,10 +1,11 @@
|
|||
import { unarray } from '@peertube/peertube-core-utils'
|
||||
import { arrayify } from '@peertube/peertube-core-utils'
|
||||
import { peertubeTruncate } from '@server/helpers/core-utils.js'
|
||||
import { ActivityPubActor } from 'packages/models/src/activitypub/activitypub-actor.js'
|
||||
import validator from 'validator'
|
||||
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants.js'
|
||||
import { exists, isArray, isDateValid } from '../misc.js'
|
||||
import { isHostValid } from '../servers.js'
|
||||
import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc.js'
|
||||
import { isActivityPubHTMLUrlValid, isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc.js'
|
||||
|
||||
export function isActorEndpointsObjectValid (endpointObject: any) {
|
||||
if (endpointObject?.sharedInbox) {
|
||||
|
@ -62,7 +63,7 @@ export function isActorDeleteActivityValid (activity: any) {
|
|||
return isBaseActivityValid(activity, 'Delete')
|
||||
}
|
||||
|
||||
export function sanitizeAndCheckActorObject (actor: any) {
|
||||
export function sanitizeAndCheckActorObject (actor: ActivityPubActor) {
|
||||
if (!isActorTypeValid(actor.type)) return false
|
||||
|
||||
normalizeActor(actor)
|
||||
|
@ -71,43 +72,16 @@ export function sanitizeAndCheckActorObject (actor: any) {
|
|||
isActivityPubUrlValid(actor.id) &&
|
||||
isActivityPubUrlValid(actor.inbox) &&
|
||||
isActorPreferredUsernameValid(actor.preferredUsername) &&
|
||||
isActivityPubUrlValid(actor.url) &&
|
||||
isActorPublicKeyObjectValid(actor.publicKey) &&
|
||||
isActorEndpointsObjectValid(actor.endpoints) &&
|
||||
|
||||
(!actor.outbox || isActivityPubUrlValid(actor.outbox)) &&
|
||||
(!actor.following || isActivityPubUrlValid(actor.following)) &&
|
||||
(!actor.followers || isActivityPubUrlValid(actor.followers)) &&
|
||||
|
||||
setValidAttributedTo(actor) &&
|
||||
setValidDescription(actor) &&
|
||||
// If this is a group (a channel), it should be attributed to an account
|
||||
// In PeerTube we use this to attach a video channel to a specific account
|
||||
(actor.type !== 'Group' || actor.attributedTo.length !== 0)
|
||||
}
|
||||
|
||||
export function normalizeActor (actor: any) {
|
||||
if (!actor) return
|
||||
|
||||
if (!actor.url) {
|
||||
actor.url = actor.id
|
||||
} else if (isArray(actor.url)) {
|
||||
actor.url = unarray(actor.url)
|
||||
} else if (typeof actor.url !== 'string') {
|
||||
actor.url = actor.url.href || actor.url.url
|
||||
}
|
||||
|
||||
if (!isDateValid(actor.published)) actor.published = undefined
|
||||
|
||||
if (actor.summary && typeof actor.summary === 'string') {
|
||||
actor.summary = peertubeTruncate(actor.summary, { length: CONSTRAINTS_FIELDS.USERS.DESCRIPTION.max })
|
||||
|
||||
if (actor.summary.length < CONSTRAINTS_FIELDS.USERS.DESCRIPTION.min) {
|
||||
actor.summary = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function isValidActorHandle (handle: string) {
|
||||
if (!exists(handle)) return false
|
||||
|
||||
|
@ -121,8 +95,38 @@ export function areValidActorHandles (handles: string[]) {
|
|||
return isArray(handles) && handles.every(h => isValidActorHandle(h))
|
||||
}
|
||||
|
||||
export function setValidDescription (obj: any) {
|
||||
if (!obj.summary) obj.summary = null
|
||||
// ---------------------------------------------------------------------------
|
||||
// Private
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
return true
|
||||
function normalizeActor (actor: ActivityPubActor) {
|
||||
if (!actor) return
|
||||
|
||||
setValidUrls(actor)
|
||||
setValidAttributedTo(actor)
|
||||
setValidDescription(actor)
|
||||
|
||||
if (!isDateValid(actor.published)) actor.published = undefined
|
||||
|
||||
if (actor.summary && typeof actor.summary === 'string') {
|
||||
actor.summary = peertubeTruncate(actor.summary, { length: CONSTRAINTS_FIELDS.USERS.DESCRIPTION.max })
|
||||
|
||||
if (actor.summary.length < CONSTRAINTS_FIELDS.USERS.DESCRIPTION.min) {
|
||||
actor.summary = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setValidDescription (actor: ActivityPubActor) {
|
||||
if (!actor.summary) actor.summary = null
|
||||
}
|
||||
|
||||
function setValidUrls (actor: any) {
|
||||
if (!actor.url) {
|
||||
actor.url = []
|
||||
return
|
||||
}
|
||||
|
||||
actor.url = arrayify(actor.url)
|
||||
.filter(u => isActivityPubHTMLUrlValid(u))
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import validator from 'validator'
|
||||
import { CONFIG } from '@server/initializers/config.js'
|
||||
import { ActivityHtmlUrlObject } from 'packages/models/src/activitypub/index.js'
|
||||
import validator from 'validator'
|
||||
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants.js'
|
||||
import { exists } from '../misc.js'
|
||||
|
||||
function isUrlValid (url: string) {
|
||||
export function isUrlValid (url: string) {
|
||||
const isURLOptions = {
|
||||
require_host: true,
|
||||
require_tld: true,
|
||||
|
@ -20,11 +21,11 @@ function isUrlValid (url: string) {
|
|||
return exists(url) && validator.default.isURL('' + url, isURLOptions)
|
||||
}
|
||||
|
||||
function isActivityPubUrlValid (url: string) {
|
||||
export function isActivityPubUrlValid (url: string) {
|
||||
return isUrlValid(url) && validator.default.isLength('' + url, CONSTRAINTS_FIELDS.ACTORS.URL)
|
||||
}
|
||||
|
||||
function isBaseActivityValid (activity: any, type: string) {
|
||||
export function isBaseActivityValid (activity: any, type: string) {
|
||||
return activity.type === type &&
|
||||
isActivityPubUrlValid(activity.id) &&
|
||||
isObjectValid(activity.actor) &&
|
||||
|
@ -32,19 +33,26 @@ function isBaseActivityValid (activity: any, type: string) {
|
|||
isUrlCollectionValid(activity.cc)
|
||||
}
|
||||
|
||||
function isUrlCollectionValid (collection: any) {
|
||||
export function isUrlCollectionValid (collection: any) {
|
||||
return collection === undefined ||
|
||||
(Array.isArray(collection) && collection.every(t => isActivityPubUrlValid(t)))
|
||||
}
|
||||
|
||||
function isObjectValid (object: any) {
|
||||
export function isObjectValid (object: any) {
|
||||
return exists(object) &&
|
||||
(
|
||||
isActivityPubUrlValid(object) || isActivityPubUrlValid(object.id)
|
||||
)
|
||||
}
|
||||
|
||||
function setValidAttributedTo (obj: any) {
|
||||
export function isActivityPubHTMLUrlValid (url: ActivityHtmlUrlObject) {
|
||||
return url &&
|
||||
url.type === 'Link' &&
|
||||
url.mediaType === 'text/html' &&
|
||||
isActivityPubUrlValid(url.href)
|
||||
}
|
||||
|
||||
export function setValidAttributedTo (obj: any) {
|
||||
if (Array.isArray(obj.attributedTo) === false) {
|
||||
obj.attributedTo = []
|
||||
return true
|
||||
|
@ -58,19 +66,10 @@ function setValidAttributedTo (obj: any) {
|
|||
return true
|
||||
}
|
||||
|
||||
function isActivityPubVideoDurationValid (value: string) {
|
||||
export function isActivityPubVideoDurationValid (value: string) {
|
||||
// https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
|
||||
return exists(value) &&
|
||||
typeof value === 'string' &&
|
||||
value.startsWith('PT') &&
|
||||
value.endsWith('S')
|
||||
}
|
||||
|
||||
export {
|
||||
isUrlValid,
|
||||
isActivityPubUrlValid,
|
||||
isBaseActivityValid,
|
||||
setValidAttributedTo,
|
||||
isObjectValid,
|
||||
isActivityPubVideoDurationValid
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue