]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/server/plugin.ts
Fix socket notification with multiple user tabs
[github/Chocobozzz/PeerTube.git] / server / models / server / plugin.ts
CommitLineData
ad91e700
C
1import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2import { getSort, throwIfNotValid } from '../utils'
345da516 3import {
b5f919ac
C
4 isPluginDescriptionValid,
5 isPluginHomepage,
345da516
C
6 isPluginNameValid,
7 isPluginTypeValid,
8 isPluginVersionValid
9} from '../../helpers/custom-validators/plugins'
ad91e700
C
10import { PluginType } from '../../../shared/models/plugins/plugin.type'
11import { PeerTubePlugin } from '../../../shared/models/plugins/peertube-plugin.model'
b2195faf 12import { FindAndCountOptions, json } from 'sequelize'
ba211e73 13import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model'
ad91e700
C
14
15@DefaultScope(() => ({
16 attributes: {
17 exclude: [ 'storage' ]
18 }
19}))
345da516
C
20
21@Table({
22 tableName: 'plugin',
23 indexes: [
24 {
dba85a1e 25 fields: [ 'name', 'type' ],
345da516
C
26 unique: true
27 }
28 ]
29})
30export class PluginModel extends Model<PluginModel> {
31
32 @AllowNull(false)
33 @Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name'))
34 @Column
35 name: string
36
37 @AllowNull(false)
38 @Is('PluginType', value => throwIfNotValid(value, isPluginTypeValid, 'type'))
39 @Column
40 type: number
41
42 @AllowNull(false)
43 @Is('PluginVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
44 @Column
45 version: string
46
b5f919ac
C
47 @AllowNull(true)
48 @Is('PluginLatestVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
49 @Column
50 latestVersion: string
51
345da516
C
52 @AllowNull(false)
53 @Column
54 enabled: boolean
55
56 @AllowNull(false)
57 @Column
58 uninstalled: boolean
59
60 @AllowNull(false)
345da516
C
61 @Column
62 peertubeEngine: string
63
64 @AllowNull(true)
65 @Is('PluginDescription', value => throwIfNotValid(value, isPluginDescriptionValid, 'description'))
66 @Column
67 description: string
68
dba85a1e
C
69 @AllowNull(false)
70 @Is('PluginHomepage', value => throwIfNotValid(value, isPluginHomepage, 'homepage'))
71 @Column
72 homepage: string
73
345da516
C
74 @AllowNull(true)
75 @Column(DataType.JSONB)
76 settings: any
77
78 @AllowNull(true)
79 @Column(DataType.JSONB)
80 storage: any
81
82 @CreatedAt
83 createdAt: Date
84
85 @UpdatedAt
86 updatedAt: Date
87
88 static listEnabledPluginsAndThemes () {
89 const query = {
90 where: {
91 enabled: true,
92 uninstalled: false
93 }
94 }
95
96 return PluginModel.findAll(query)
97 }
98
dba85a1e
C
99 static loadByNpmName (npmName: string) {
100 const name = this.normalizePluginName(npmName)
101 const type = this.getTypeFromNpmName(npmName)
102
2c053942
C
103 const query = {
104 where: {
dba85a1e
C
105 name,
106 type
2c053942
C
107 }
108 }
109
110 return PluginModel.findOne(query)
111 }
112
b5f919ac 113 static getSetting (pluginName: string, pluginType: PluginType, settingName: string) {
ad91e700
C
114 const query = {
115 attributes: [ 'settings' ],
116 where: {
b5f919ac
C
117 name: pluginName,
118 type: pluginType
ad91e700
C
119 }
120 }
121
122 return PluginModel.findOne(query)
b5f919ac
C
123 .then(p => {
124 if (!p || !p.settings) return undefined
ad91e700 125
b5f919ac 126 return p.settings[settingName]
ad91e700
C
127 })
128 }
129
b5f919ac 130 static setSetting (pluginName: string, pluginType: PluginType, settingName: string, settingValue: string) {
f023a19c
C
131 const query = {
132 where: {
b5f919ac
C
133 name: pluginName,
134 type: pluginType
f023a19c
C
135 }
136 }
137
ad91e700
C
138 const toSave = {
139 [`settings.${settingName}`]: settingValue
140 }
141
142 return PluginModel.update(toSave, query)
143 .then(() => undefined)
144 }
145
b2195faf
C
146 static getData (pluginName: string, pluginType: PluginType, key: string) {
147 const query = {
148 raw: true,
149 attributes: [ [ json('storage.' + key), 'value' ] as any ], // FIXME: typings
150 where: {
151 name: pluginName,
152 type: pluginType
153 }
154 }
155
156 return PluginModel.findOne(query)
109d893f 157 .then((c: any) => {
b2195faf 158 if (!c) return undefined
9fa6ca16
C
159 const value = c.value
160
161 if (typeof value === 'string' && value.startsWith('{')) {
162 try {
163 return JSON.parse(value)
164 } catch {
165 return value
166 }
167 }
b2195faf
C
168
169 return c.value
170 })
171 }
172
173 static storeData (pluginName: string, pluginType: PluginType, key: string, data: any) {
174 const query = {
175 where: {
176 name: pluginName,
177 type: pluginType
178 }
179 }
180
181 const toSave = {
182 [`storage.${key}`]: data
183 }
184
185 return PluginModel.update(toSave, query)
186 .then(() => undefined)
187 }
188
ad91e700 189 static listForApi (options: {
6702a1b2 190 pluginType?: PluginType,
ad91e700
C
191 uninstalled?: boolean,
192 start: number,
193 count: number,
194 sort: string
195 }) {
8d2be0ed 196 const { uninstalled = false } = options
ad91e700
C
197 const query: FindAndCountOptions = {
198 offset: options.start,
199 limit: options.count,
200 order: getSort(options.sort),
8d2be0ed
C
201 where: {
202 uninstalled
203 }
ad91e700
C
204 }
205
6702a1b2 206 if (options.pluginType) query.where['type'] = options.pluginType
ad91e700
C
207
208 return PluginModel
209 .findAndCountAll(query)
210 .then(({ rows, count }) => {
211 return { total: count, data: rows }
212 })
213 }
214
6702a1b2
C
215 static listInstalled () {
216 const query = {
217 where: {
218 uninstalled: false
219 }
220 }
221
222 return PluginModel.findAll(query)
223 }
224
225 static normalizePluginName (npmName: string) {
226 return npmName.replace(/^peertube-((theme)|(plugin))-/, '')
dba85a1e
C
227 }
228
229 static getTypeFromNpmName (npmName: string) {
230 return npmName.startsWith('peertube-plugin-')
231 ? PluginType.PLUGIN
232 : PluginType.THEME
233 }
234
b5f919ac
C
235 static buildNpmName (name: string, type: PluginType) {
236 if (type === PluginType.THEME) return 'peertube-theme-' + name
237
238 return 'peertube-plugin-' + name
239 }
240
ba211e73
C
241 getPublicSettings (registeredSettings: RegisterServerSettingOptions[]) {
242 const result: { [ name: string ]: string } = {}
243 const settings = this.settings || {}
244
245 for (const r of registeredSettings) {
246 if (r.private !== false) continue
247
248 result[r.name] = settings[r.name] || r.default || null
249 }
250
251 return result
252 }
253
ad91e700
C
254 toFormattedJSON (): PeerTubePlugin {
255 return {
256 name: this.name,
257 type: this.type,
258 version: this.version,
b5f919ac 259 latestVersion: this.latestVersion,
ad91e700
C
260 enabled: this.enabled,
261 uninstalled: this.uninstalled,
262 peertubeEngine: this.peertubeEngine,
263 description: this.description,
dba85a1e 264 homepage: this.homepage,
ad91e700
C
265 settings: this.settings,
266 createdAt: this.createdAt,
267 updatedAt: this.updatedAt
268 }
f023a19c
C
269 }
270
345da516 271}