diff options
Diffstat (limited to 'server/helpers/custom-validators/plugins.ts')
-rw-r--r-- | server/helpers/custom-validators/plugins.ts | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/server/helpers/custom-validators/plugins.ts b/server/helpers/custom-validators/plugins.ts new file mode 100644 index 000000000..ff687dc3f --- /dev/null +++ b/server/helpers/custom-validators/plugins.ts | |||
@@ -0,0 +1,82 @@ | |||
1 | import { exists, isArray, isSafePath } from './misc' | ||
2 | import * as validator from 'validator' | ||
3 | import { PluginType } from '../../../shared/models/plugins/plugin.type' | ||
4 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' | ||
5 | import { PluginPackageJson } from '../../../shared/models/plugins/plugin-package-json.model' | ||
6 | import { isUrlValid } from './activitypub/misc' | ||
7 | |||
8 | const PLUGINS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.PLUGINS | ||
9 | |||
10 | function isPluginTypeValid (value: any) { | ||
11 | return exists(value) && validator.isInt('' + value) && PluginType[value] !== undefined | ||
12 | } | ||
13 | |||
14 | function isPluginNameValid (value: string) { | ||
15 | return exists(value) && | ||
16 | validator.isLength(value, PLUGINS_CONSTRAINTS_FIELDS.NAME) && | ||
17 | validator.matches(value, /^[a-z\-]+$/) | ||
18 | } | ||
19 | |||
20 | function isPluginDescriptionValid (value: string) { | ||
21 | return exists(value) && validator.isLength(value, PLUGINS_CONSTRAINTS_FIELDS.DESCRIPTION) | ||
22 | } | ||
23 | |||
24 | function isPluginVersionValid (value: string) { | ||
25 | if (!exists(value)) return false | ||
26 | |||
27 | const parts = (value + '').split('.') | ||
28 | |||
29 | return parts.length === 3 && parts.every(p => validator.isInt(p)) | ||
30 | } | ||
31 | |||
32 | function isPluginEngineValid (engine: any) { | ||
33 | return exists(engine) && exists(engine.peertube) | ||
34 | } | ||
35 | |||
36 | function isStaticDirectoriesValid (staticDirs: any) { | ||
37 | if (!exists(staticDirs) || typeof staticDirs !== 'object') return false | ||
38 | |||
39 | for (const key of Object.keys(staticDirs)) { | ||
40 | if (!isSafePath(staticDirs[key])) return false | ||
41 | } | ||
42 | |||
43 | return true | ||
44 | } | ||
45 | |||
46 | function isClientScriptsValid (clientScripts: any[]) { | ||
47 | return isArray(clientScripts) && | ||
48 | clientScripts.every(c => { | ||
49 | return isSafePath(c.script) && isArray(c.scopes) | ||
50 | }) | ||
51 | } | ||
52 | |||
53 | function isCSSPathsValid (css: any[]) { | ||
54 | return isArray(css) && css.every(c => isSafePath(c)) | ||
55 | } | ||
56 | |||
57 | function isPackageJSONValid (packageJSON: PluginPackageJson, pluginType: PluginType) { | ||
58 | return isPluginNameValid(packageJSON.name) && | ||
59 | isPluginDescriptionValid(packageJSON.description) && | ||
60 | isPluginEngineValid(packageJSON.engine) && | ||
61 | isUrlValid(packageJSON.homepage) && | ||
62 | exists(packageJSON.author) && | ||
63 | isUrlValid(packageJSON.bugs) && | ||
64 | (pluginType === PluginType.THEME || isSafePath(packageJSON.library)) && | ||
65 | isStaticDirectoriesValid(packageJSON.staticDirs) && | ||
66 | isCSSPathsValid(packageJSON.css) && | ||
67 | isClientScriptsValid(packageJSON.clientScripts) | ||
68 | } | ||
69 | |||
70 | function isLibraryCodeValid (library: any) { | ||
71 | return typeof library.register === 'function' | ||
72 | && typeof library.unregister === 'function' | ||
73 | } | ||
74 | |||
75 | export { | ||
76 | isPluginTypeValid, | ||
77 | isPackageJSONValid, | ||
78 | isPluginVersionValid, | ||
79 | isPluginNameValid, | ||
80 | isPluginDescriptionValid, | ||
81 | isLibraryCodeValid | ||
82 | } | ||