mirror of https://github.com/Chocobozzz/PeerTube
Sanitize url to not end with implicit ports
parent
6725d05c5f
commit
225a89c2af
|
@ -1,19 +1,15 @@
|
|||
import * as express from 'express'
|
||||
import { UserRight } from '../../../../shared/models/users'
|
||||
import { getFormattedObjects, getServerActor, loadActorUrlOrGetFromWebfinger, logger, retryTransactionWrapper } from '../../../helpers'
|
||||
import { sequelizeTypescript, SERVER_ACTOR_NAME } from '../../../initializers'
|
||||
import {
|
||||
getFormattedObjects, getServerActor, loadActorUrlOrGetFromWebfinger, logger, retryTransactionWrapper,
|
||||
sanitizeHost
|
||||
} from '../../../helpers'
|
||||
import { REMOTE_SCHEME, sequelizeTypescript, SERVER_ACTOR_NAME } from '../../../initializers'
|
||||
import { getOrCreateActorAndServerAndModel } from '../../../lib/activitypub'
|
||||
import { sendFollow, sendUndoFollow } from '../../../lib/activitypub/send'
|
||||
import {
|
||||
asyncMiddleware,
|
||||
authenticate,
|
||||
ensureUserHasRight,
|
||||
paginationValidator,
|
||||
removeFollowingValidator,
|
||||
setBodyHostsPort,
|
||||
setFollowersSort,
|
||||
setFollowingSort,
|
||||
setPagination
|
||||
asyncMiddleware, authenticate, ensureUserHasRight, paginationValidator, removeFollowingValidator, setBodyHostsPort,
|
||||
setFollowersSort, setFollowingSort, setPagination
|
||||
} from '../../../middlewares'
|
||||
import { followersSortValidator, followingSortValidator, followValidator } from '../../../middlewares/validators'
|
||||
import { ActorModel } from '../../../models/activitypub/actor'
|
||||
|
@ -82,10 +78,12 @@ async function followRetry (req: express.Request, res: express.Response, next: e
|
|||
const actorName = SERVER_ACTOR_NAME
|
||||
|
||||
for (const host of hosts) {
|
||||
const sanitizedHost = sanitizeHost(host, REMOTE_SCHEME.HTTP)
|
||||
|
||||
// We process each host in a specific transaction
|
||||
// First, we add the follow request in the database
|
||||
// Then we send the follow request to other actor
|
||||
const p = loadActorUrlOrGetFromWebfinger(actorName, host)
|
||||
const p = loadActorUrlOrGetFromWebfinger(actorName, sanitizedHost)
|
||||
.then(actorUrl => getOrCreateActorAndServerAndModel(actorUrl))
|
||||
.then(targetActor => {
|
||||
const options = {
|
||||
|
@ -95,7 +93,7 @@ async function followRetry (req: express.Request, res: express.Response, next: e
|
|||
|
||||
return retryTransactionWrapper(follow, options)
|
||||
})
|
||||
.catch(err => logger.warn('Cannot follow server %s.', host, err))
|
||||
.catch(err => logger.warn('Cannot follow server %s.', sanitizedHost, err))
|
||||
|
||||
tasks.push(p)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,26 @@ import * as mkdirp from 'mkdirp'
|
|||
import { join } from 'path'
|
||||
import * as pem from 'pem'
|
||||
import * as rimraf from 'rimraf'
|
||||
import { URL } from 'url'
|
||||
|
||||
function sanitizeUrl (url: string) {
|
||||
const urlObject = new URL(url)
|
||||
|
||||
if (urlObject.protocol === 'https:' && urlObject.port === '443') {
|
||||
urlObject.port = ''
|
||||
} else if (urlObject.protocol === 'http:' && urlObject.port === '80') {
|
||||
urlObject.port = ''
|
||||
}
|
||||
|
||||
return urlObject.href.replace(/\/$/, '')
|
||||
}
|
||||
|
||||
// Don't import remote scheme from constants because we are in core utils
|
||||
function sanitizeHost (host: string, remoteScheme: string) {
|
||||
let toRemove = remoteScheme === 'https' ? 443 : 80
|
||||
|
||||
return host.replace(new RegExp(`:${toRemove}$`), '')
|
||||
}
|
||||
|
||||
function isTestInstance () {
|
||||
return process.env.NODE_ENV === 'test'
|
||||
|
@ -114,6 +134,8 @@ export {
|
|||
root,
|
||||
escapeHTML,
|
||||
pageToStartAndCount,
|
||||
sanitizeUrl,
|
||||
sanitizeHost,
|
||||
|
||||
promisify0,
|
||||
promisify1,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { CONFIG } from '../../initializers'
|
||||
import { CONFIG, REMOTE_SCHEME } from '../../initializers'
|
||||
import { sanitizeHost } from '../core-utils'
|
||||
import { exists } from './misc'
|
||||
|
||||
function isWebfingerResourceValid (value: string) {
|
||||
|
@ -11,7 +12,7 @@ function isWebfingerResourceValid (value: string) {
|
|||
|
||||
const host = actorParts[1]
|
||||
|
||||
return host === CONFIG.WEBSERVER.HOSTNAME || host === CONFIG.WEBSERVER.HOST
|
||||
return sanitizeHost(host, REMOTE_SCHEME.HTTP) === CONFIG.WEBSERVER.HOSTNAME
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import * as config from 'config'
|
||||
import { join } from 'path'
|
||||
import { JobCategory, JobState, VideoRateType } from '../../shared/models'
|
||||
import { FollowState } from '../../shared/models/actors'
|
||||
import { ActivityPubActorType } from '../../shared/models/activitypub'
|
||||
import { FollowState } from '../../shared/models/actors'
|
||||
import { VideoPrivacy } from '../../shared/models/videos'
|
||||
// Do not use barrels, remain constants as independent as possible
|
||||
import { isTestInstance, root } from '../helpers/core-utils'
|
||||
import { isTestInstance, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const LAST_MIGRATION_VERSION = 135
|
||||
const LAST_MIGRATION_VERSION = 140
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -38,6 +38,44 @@ const OAUTH_LIFETIME = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Number of points we add/remove from a friend after a successful/bad request
|
||||
const SERVERS_SCORE = {
|
||||
PENALTY: -10,
|
||||
BONUS: 10,
|
||||
BASE: 100,
|
||||
MAX: 1000
|
||||
}
|
||||
|
||||
const FOLLOW_STATES: { [ id: string ]: FollowState } = {
|
||||
PENDING: 'pending',
|
||||
ACCEPTED: 'accepted'
|
||||
}
|
||||
|
||||
const REMOTE_SCHEME = {
|
||||
HTTP: 'https',
|
||||
WS: 'wss'
|
||||
}
|
||||
|
||||
const JOB_STATES: { [ id: string ]: JobState } = {
|
||||
PENDING: 'pending',
|
||||
PROCESSING: 'processing',
|
||||
ERROR: 'error',
|
||||
SUCCESS: 'success'
|
||||
}
|
||||
const JOB_CATEGORIES: { [ id: string ]: JobCategory } = {
|
||||
TRANSCODING: 'transcoding',
|
||||
ACTIVITYPUB_HTTP: 'activitypub-http'
|
||||
}
|
||||
// How many maximum jobs we fetch from the database per cycle
|
||||
const JOBS_FETCH_LIMIT_PER_CYCLE = {
|
||||
transcoding: 10,
|
||||
httpRequest: 20
|
||||
}
|
||||
// 1 minutes
|
||||
let JOBS_FETCHING_INTERVAL = 60000
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const CONFIG = {
|
||||
LISTEN: {
|
||||
PORT: config.get<number>('listen.port')
|
||||
|
@ -93,8 +131,6 @@ const CONFIG = {
|
|||
}
|
||||
}
|
||||
}
|
||||
CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
||||
CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
||||
|
||||
const AVATARS_DIR = {
|
||||
ACCOUNT: join(CONFIG.STORAGE.AVATARS_DIR, 'account')
|
||||
|
@ -238,44 +274,6 @@ const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Number of points we add/remove from a friend after a successful/bad request
|
||||
const SERVERS_SCORE = {
|
||||
PENALTY: -10,
|
||||
BONUS: 10,
|
||||
BASE: 100,
|
||||
MAX: 1000
|
||||
}
|
||||
|
||||
const FOLLOW_STATES: { [ id: string ]: FollowState } = {
|
||||
PENDING: 'pending',
|
||||
ACCEPTED: 'accepted'
|
||||
}
|
||||
|
||||
const REMOTE_SCHEME = {
|
||||
HTTP: 'https',
|
||||
WS: 'wss'
|
||||
}
|
||||
|
||||
const JOB_STATES: { [ id: string ]: JobState } = {
|
||||
PENDING: 'pending',
|
||||
PROCESSING: 'processing',
|
||||
ERROR: 'error',
|
||||
SUCCESS: 'success'
|
||||
}
|
||||
const JOB_CATEGORIES: { [ id: string ]: JobCategory } = {
|
||||
TRANSCODING: 'transcoding',
|
||||
ACTIVITYPUB_HTTP: 'activitypub-http'
|
||||
}
|
||||
// How many maximum jobs we fetch from the database per cycle
|
||||
const JOBS_FETCH_LIMIT_PER_CYCLE = {
|
||||
transcoding: 10,
|
||||
httpRequest: 20
|
||||
}
|
||||
// 1 minutes
|
||||
let JOBS_FETCHING_INTERVAL = 60000
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const PRIVATE_RSA_KEY_SIZE = 2048
|
||||
|
||||
// Password encryption
|
||||
|
@ -334,6 +332,9 @@ if (isTestInstance() === true) {
|
|||
ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE = 2
|
||||
}
|
||||
|
||||
CONFIG.WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT)
|
||||
CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import { DataType } from 'sequelize-typescript'
|
||||
import { createPrivateAndPublicKeys } from '../../helpers'
|
||||
import { CONFIG } from '../constants'
|
||||
|
||||
async function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
queryInterface: Sequelize.QueryInterface,
|
||||
sequelize: Sequelize.Sequelize
|
||||
}): Promise<void> {
|
||||
const toReplace = CONFIG.WEBSERVER.HOSTNAME + ':443'
|
||||
const by = CONFIG.WEBSERVER.HOST
|
||||
const replacer = column => `replace("${column}", '${toReplace}', '${by}')`
|
||||
|
||||
{
|
||||
const query = `UPDATE video SET url = ${replacer('url')}`
|
||||
await utils.sequelize.query(query)
|
||||
}
|
||||
|
||||
{
|
||||
const query = `
|
||||
UPDATE actor SET url = ${replacer('url')}, "inboxUrl" = ${replacer('inboxUrl')}, "outboxUrl" = ${replacer('outboxUrl')},
|
||||
"sharedInboxUrl" = ${replacer('sharedInboxUrl')}, "followersUrl" = ${replacer('followersUrl')},
|
||||
"followingUrl" = ${replacer('followingUrl')}
|
||||
`
|
||||
await utils.sequelize.query(query)
|
||||
}
|
||||
|
||||
{
|
||||
const query = `UPDATE server SET host = replace(host, ':443', '')`
|
||||
await utils.sequelize.query(query)
|
||||
}
|
||||
}
|
||||
|
||||
function down (options) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
Loading…
Reference in New Issue