]>
Commit | Line | Data |
---|---|---|
345da516 C |
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 | ||
f023a19c C |
20 | function isNpmPluginNameValid (value: string) { |
21 | return exists(value) && | |
22 | validator.isLength(value, PLUGINS_CONSTRAINTS_FIELDS.NAME) && | |
23 | validator.matches(value, /^[a-z\-]+$/) && | |
24 | (value.startsWith('peertube-plugin-') || value.startsWith('peertube-theme-')) | |
25 | } | |
26 | ||
345da516 C |
27 | function isPluginDescriptionValid (value: string) { |
28 | return exists(value) && validator.isLength(value, PLUGINS_CONSTRAINTS_FIELDS.DESCRIPTION) | |
29 | } | |
30 | ||
31 | function isPluginVersionValid (value: string) { | |
32 | if (!exists(value)) return false | |
33 | ||
34 | const parts = (value + '').split('.') | |
35 | ||
36 | return parts.length === 3 && parts.every(p => validator.isInt(p)) | |
37 | } | |
38 | ||
39 | function isPluginEngineValid (engine: any) { | |
40 | return exists(engine) && exists(engine.peertube) | |
41 | } | |
42 | ||
dba85a1e C |
43 | function isPluginHomepage (value: string) { |
44 | return isUrlValid(value) | |
45 | } | |
46 | ||
d75db01f | 47 | function areStaticDirectoriesValid (staticDirs: any) { |
345da516 C |
48 | if (!exists(staticDirs) || typeof staticDirs !== 'object') return false |
49 | ||
50 | for (const key of Object.keys(staticDirs)) { | |
51 | if (!isSafePath(staticDirs[key])) return false | |
52 | } | |
53 | ||
54 | return true | |
55 | } | |
56 | ||
d75db01f | 57 | function areClientScriptsValid (clientScripts: any[]) { |
345da516 C |
58 | return isArray(clientScripts) && |
59 | clientScripts.every(c => { | |
60 | return isSafePath(c.script) && isArray(c.scopes) | |
61 | }) | |
62 | } | |
63 | ||
d75db01f C |
64 | function areTranslationPathsValid (translations: any) { |
65 | if (!exists(translations) || typeof translations !== 'object') return false | |
66 | ||
67 | for (const key of Object.keys(translations)) { | |
68 | if (!isSafePath(translations[key])) return false | |
69 | } | |
70 | ||
71 | return true | |
72 | } | |
73 | ||
74 | function areCSSPathsValid (css: any[]) { | |
345da516 C |
75 | return isArray(css) && css.every(c => isSafePath(c)) |
76 | } | |
77 | ||
503c6f44 C |
78 | function isThemeNameValid (name: string) { |
79 | return isPluginNameValid(name) | |
7cd4d2ba C |
80 | } |
81 | ||
345da516 | 82 | function isPackageJSONValid (packageJSON: PluginPackageJson, pluginType: PluginType) { |
f023a19c | 83 | return isNpmPluginNameValid(packageJSON.name) && |
345da516 C |
84 | isPluginDescriptionValid(packageJSON.description) && |
85 | isPluginEngineValid(packageJSON.engine) && | |
dba85a1e | 86 | isPluginHomepage(packageJSON.homepage) && |
345da516 C |
87 | exists(packageJSON.author) && |
88 | isUrlValid(packageJSON.bugs) && | |
89 | (pluginType === PluginType.THEME || isSafePath(packageJSON.library)) && | |
d75db01f C |
90 | areStaticDirectoriesValid(packageJSON.staticDirs) && |
91 | areCSSPathsValid(packageJSON.css) && | |
92 | areClientScriptsValid(packageJSON.clientScripts) && | |
93 | areTranslationPathsValid(packageJSON.translations) | |
345da516 C |
94 | } |
95 | ||
96 | function isLibraryCodeValid (library: any) { | |
97 | return typeof library.register === 'function' | |
98 | && typeof library.unregister === 'function' | |
99 | } | |
100 | ||
101 | export { | |
102 | isPluginTypeValid, | |
103 | isPackageJSONValid, | |
503c6f44 | 104 | isThemeNameValid, |
dba85a1e | 105 | isPluginHomepage, |
345da516 C |
106 | isPluginVersionValid, |
107 | isPluginNameValid, | |
108 | isPluginDescriptionValid, | |
f023a19c C |
109 | isLibraryCodeValid, |
110 | isNpmPluginNameValid | |
345da516 | 111 | } |