Add ability to install alpha/beta/rc plugin

This commit is contained in:
Chocobozzz 2022-11-14 14:49:50 +01:00
parent a742347d50
commit ff91b644fb
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
9 changed files with 90 additions and 18 deletions

View File

@ -1,9 +1,9 @@
import { exists, isArray, isSafePath } from './misc'
import validator from 'validator'
import { PluginPackageJSON } from '../../../shared/models/plugins/plugin-package-json.model'
import { PluginType } from '../../../shared/models/plugins/plugin.type'
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
import { PluginPackageJSON } from '../../../shared/models/plugins/plugin-package-json.model'
import { isUrlValid } from './activitypub/misc'
import { exists, isArray, isSafePath } from './misc'
const PLUGINS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.PLUGINS
@ -29,7 +29,7 @@ function isPluginDescriptionValid (value: string) {
return exists(value) && validator.isLength(value, PLUGINS_CONSTRAINTS_FIELDS.DESCRIPTION)
}
function isPluginVersionValid (value: string) {
function isPluginStableVersionValid (value: string) {
if (!exists(value)) return false
const parts = (value + '').split('.')
@ -37,6 +37,19 @@ function isPluginVersionValid (value: string) {
return parts.length === 3 && parts.every(p => validator.isInt(p))
}
function isPluginStableOrUnstableVersionValid (value: string) {
if (!exists(value)) return false
// suffix is beta.x or alpha.x
const [ stable, suffix ] = value.split('-')
if (!isPluginStableVersionValid(stable)) return false
const suffixRegex = /^(rc|alpha|beta)\.\d+$/
if (suffix && !suffixRegex.test(suffix)) return false
return true
}
function isPluginEngineValid (engine: any) {
return exists(engine) && exists(engine.peertube)
}
@ -156,7 +169,8 @@ export {
isPackageJSONValid,
isThemeNameValid,
isPluginHomepage,
isPluginVersionValid,
isPluginStableVersionValid,
isPluginStableOrUnstableVersionValid,
isPluginNameValid,
isPluginDescriptionValid,
isLibraryCodeValid,

View File

@ -1,7 +1,7 @@
import { outputJSON, pathExists } from 'fs-extra'
import { join } from 'path'
import { execShell } from '../../helpers/core-utils'
import { isNpmPluginNameValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins'
import { isNpmPluginNameValid, isPluginStableOrUnstableVersionValid } from '../../helpers/custom-validators/plugins'
import { logger } from '../../helpers/logger'
import { CONFIG } from '../../initializers/config'
import { getLatestPluginVersion } from './plugin-index'
@ -69,5 +69,5 @@ function checkNpmPluginNameOrThrow (name: string) {
}
function checkPluginVersionOrThrow (name: string) {
if (!isPluginVersionValid(name)) throw new Error('Invalid NPM plugin version to install')
if (!isPluginStableOrUnstableVersionValid(name)) throw new Error('Invalid NPM plugin version to install')
}

View File

@ -4,7 +4,12 @@ import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
import { PluginType } from '../../../shared/models/plugins/plugin.type'
import { InstallOrUpdatePlugin } from '../../../shared/models/plugins/server/api/install-plugin.model'
import { exists, isBooleanValid, isSafePath, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
import { isNpmPluginNameValid, isPluginNameValid, isPluginTypeValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins'
import {
isNpmPluginNameValid,
isPluginNameValid,
isPluginStableOrUnstableVersionValid,
isPluginTypeValid
} from '../../helpers/custom-validators/plugins'
import { CONFIG } from '../../initializers/config'
import { PluginManager } from '../../lib/plugins/plugin-manager'
import { PluginModel } from '../../models/server/plugin'
@ -19,7 +24,7 @@ const getPluginValidator = (pluginType: PluginType, withVersion = true) => {
if (withVersion) {
validators.push(
param('pluginVersion')
.custom(isPluginVersionValid)
.custom(isPluginStableOrUnstableVersionValid)
)
}
@ -113,7 +118,7 @@ const installOrUpdatePluginValidator = [
.custom(isNpmPluginNameValid),
body('pluginVersion')
.optional()
.custom(isPluginVersionValid),
.custom(isPluginStableOrUnstableVersionValid),
body('path')
.optional()
.custom(isSafePath),
@ -185,7 +190,7 @@ const listAvailablePluginsValidator = [
.custom(isPluginTypeValid),
query('currentPeerTubeEngine')
.optional()
.custom(isPluginVersionValid),
.custom(isPluginStableOrUnstableVersionValid),
(req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return

View File

@ -2,7 +2,7 @@ import express from 'express'
import { param } from 'express-validator'
import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
import { isSafePath } from '../../helpers/custom-validators/misc'
import { isPluginNameValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins'
import { isPluginNameValid, isPluginStableOrUnstableVersionValid } from '../../helpers/custom-validators/plugins'
import { PluginManager } from '../../lib/plugins/plugin-manager'
import { areValidationErrors } from './shared'
@ -10,7 +10,7 @@ const serveThemeCSSValidator = [
param('themeName')
.custom(isPluginNameValid),
param('themeVersion')
.custom(isPluginVersionValid),
.custom(isPluginStableOrUnstableVersionValid),
param('staticEndpoint')
.custom(isSafePath),

View File

@ -7,8 +7,9 @@ import {
isPluginDescriptionValid,
isPluginHomepage,
isPluginNameValid,
isPluginTypeValid,
isPluginVersionValid
isPluginStableOrUnstableVersionValid,
isPluginStableVersionValid,
isPluginTypeValid
} from '../../helpers/custom-validators/plugins'
import { getSort, throwIfNotValid } from '../utils'
@ -40,12 +41,12 @@ export class PluginModel extends Model<Partial<AttributesOnly<PluginModel>>> {
type: number
@AllowNull(false)
@Is('PluginVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
@Is('PluginVersion', value => throwIfNotValid(value, isPluginStableOrUnstableVersionValid, 'version'))
@Column
version: string
@AllowNull(true)
@Is('PluginLatestVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
@Is('PluginLatestVersion', value => throwIfNotValid(value, isPluginStableVersionValid, 'version'))
@Column
latestVersion: string

View File

@ -24,7 +24,13 @@ describe('Test CLI wrapper', function () {
before(async function () {
this.timeout(30000)
server = await createSingleServer(1)
server = await createSingleServer(1, {
rates_limit: {
login: {
max: 30
}
}
})
await setAccessTokensToServers([ server ])
await server.users.create({ username: 'user_1', password: 'super_password' })
@ -240,6 +246,19 @@ describe('Test CLI wrapper', function () {
expect(res).to.not.contain('peertube-plugin-hello-world')
})
it('Should install a plugin in requested beta version', async function () {
this.timeout(60000)
await cliCommand.execWithEnv(`${cmd} plugins install --npm-name peertube-plugin-hello-world --plugin-version 0.0.21-beta.1`)
const res = await cliCommand.execWithEnv(`${cmd} plugins list`)
expect(res).to.contain('peertube-plugin-hello-world')
expect(res).to.contain('0.0.21-beta.1')
await cliCommand.execWithEnv(`${cmd} plugins uninstall --npm-name peertube-plugin-hello-world`)
})
})
describe('Manage video redundancies', function () {

View File

@ -5,3 +5,4 @@ import './dns'
import './image'
import './markdown'
import './request'
import './validator'

View File

@ -0,0 +1,32 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { expect } from 'chai'
import { isPluginStableOrUnstableVersionValid, isPluginStableVersionValid } from '@server/helpers/custom-validators/plugins'
describe('Validators', function () {
it('Should correctly check stable plugin versions', async function () {
expect(isPluginStableVersionValid('3.4.0')).to.be.true
expect(isPluginStableVersionValid('0.4.0')).to.be.true
expect(isPluginStableVersionValid('0.1.0')).to.be.true
expect(isPluginStableVersionValid('0.1.0-beta-1')).to.be.false
expect(isPluginStableVersionValid('hello')).to.be.false
expect(isPluginStableVersionValid('0.x.a')).to.be.false
})
it('Should correctly check unstable plugin versions', async function () {
expect(isPluginStableOrUnstableVersionValid('3.4.0')).to.be.true
expect(isPluginStableOrUnstableVersionValid('0.4.0')).to.be.true
expect(isPluginStableOrUnstableVersionValid('0.1.0')).to.be.true
expect(isPluginStableOrUnstableVersionValid('0.1.0-beta.1')).to.be.true
expect(isPluginStableOrUnstableVersionValid('0.1.0-alpha.45')).to.be.true
expect(isPluginStableOrUnstableVersionValid('0.1.0-rc.45')).to.be.true
expect(isPluginStableOrUnstableVersionValid('hello')).to.be.false
expect(isPluginStableOrUnstableVersionValid('0.x.a')).to.be.false
expect(isPluginStableOrUnstableVersionValid('0.1.0-rc-45')).to.be.false
expect(isPluginStableOrUnstableVersionValid('0.1.0-rc.45d')).to.be.false
})
})

View File

@ -69,7 +69,7 @@ async function pluginsListCLI (command: Command, options: OptionValues) {
const table = new CliTable3({
head: [ 'name', 'version', 'homepage' ],
colWidths: [ 50, 10, 50 ]
colWidths: [ 50, 20, 50 ]
}) as any
for (const plugin of data) {