10cff7dd739468303196af16c4e553300d95c4fa
[oweals/peertube.git] / peertube-plugins.ts
1 import * as program from 'commander'
2 import { PluginType } from '../../shared/models/plugins/plugin.type'
3 import { getAccessToken } from '../../shared/extra-utils/users/login'
4 import { getMyUserInformation } from '../../shared/extra-utils/users/users'
5 import { installPlugin, listPlugins, uninstallPlugin, updatePlugin } from '../../shared/extra-utils/server/plugins'
6 import { getServerCredentials } from './cli'
7 import { User, UserRole } from '../../shared/models/users'
8 import { PeerTubePlugin } from '../../shared/models/plugins/peertube-plugin.model'
9 import { isAbsolute } from 'path'
10
11 const Table = require('cli-table')
12
13 program
14   .name('plugins')
15   .usage('[command] [options]')
16
17 program
18   .command('list')
19   .description('List installed plugins')
20   .option('-u, --url <url>', 'Server url')
21   .option('-U, --username <username>', 'Username')
22   .option('-p, --password <token>', 'Password')
23   .option('-t, --only-themes', 'List themes only')
24   .option('-P, --only-plugins', 'List plugins only')
25   .action(() => pluginsListCLI())
26
27 program
28   .command('install')
29   .description('Install a plugin or a theme')
30   .option('-u, --url <url>', 'Server url')
31   .option('-U, --username <username>', 'Username')
32   .option('-p, --password <token>', 'Password')
33   .option('-P --path <path>', 'Install from a path')
34   .option('-n, --npm-name <npmName>', 'Install from npm')
35   .action((options) => installPluginCLI(options))
36
37 program
38   .command('update')
39   .description('Update a plugin or a theme')
40   .option('-u, --url <url>', 'Server url')
41   .option('-U, --username <username>', 'Username')
42   .option('-p, --password <token>', 'Password')
43   .option('-P --path <path>', 'Update from a path')
44   .option('-n, --npm-name <npmName>', 'Update from npm')
45   .action((options) => updatePluginCLI(options))
46
47 program
48   .command('uninstall')
49   .description('Uninstall a plugin or a theme')
50   .option('-u, --url <url>', 'Server url')
51   .option('-U, --username <username>', 'Username')
52   .option('-p, --password <token>', 'Password')
53   .option('-n, --npm-name <npmName>', 'NPM plugin/theme name')
54   .action(options => uninstallPluginCLI(options))
55
56 if (!process.argv.slice(2).length) {
57   program.outputHelp()
58 }
59
60 program.parse(process.argv)
61
62 // ----------------------------------------------------------------------------
63
64 async function pluginsListCLI () {
65   const { url, username, password } = await getServerCredentials(program)
66   const accessToken = await getAdminTokenOrDie(url, username, password)
67
68   let type: PluginType
69   if (program['onlyThemes']) type = PluginType.THEME
70   if (program['onlyPlugins']) type = PluginType.PLUGIN
71
72   const res = await listPlugins({
73     url,
74     accessToken,
75     start: 0,
76     count: 100,
77     sort: 'name',
78     type
79   })
80   const plugins: PeerTubePlugin[] = res.body.data
81
82   const table = new Table({
83     head: ['name', 'version', 'homepage'],
84     colWidths: [ 50, 10, 50 ]
85   })
86
87   for (const plugin of plugins) {
88     const npmName = plugin.type === PluginType.PLUGIN
89       ? 'peertube-plugin-' + plugin.name
90       : 'peertube-theme-' + plugin.name
91
92     table.push([
93       npmName,
94       plugin.version,
95       plugin.homepage
96     ])
97   }
98
99   console.log(table.toString())
100   process.exit(0)
101 }
102
103 async function installPluginCLI (options: any) {
104   if (!options['path'] && !options['npmName']) {
105     console.error('You need to specify the npm name or the path of the plugin you want to install.\n')
106     program.outputHelp()
107     process.exit(-1)
108   }
109
110   if (options['path'] && !isAbsolute(options['path'])) {
111     console.error('Path should be absolute.')
112     process.exit(-1)
113   }
114
115   const { url, username, password } = await getServerCredentials(options)
116   const accessToken = await getAdminTokenOrDie(url, username, password)
117
118   try {
119     await installPlugin({
120       url,
121       accessToken,
122       npmName: options['npmName'],
123       path: options['path']
124     })
125   } catch (err) {
126     console.error('Cannot install plugin.', err)
127     process.exit(-1)
128     return
129   }
130
131   console.log('Plugin installed.')
132   process.exit(0)
133 }
134
135 async function updatePluginCLI (options: any) {
136   if (!options['path'] && !options['npmName']) {
137     console.error('You need to specify the npm name or the path of the plugin you want to update.\n')
138     program.outputHelp()
139     process.exit(-1)
140   }
141
142   if (options['path'] && !isAbsolute(options['path'])) {
143     console.error('Path should be absolute.')
144     process.exit(-1)
145   }
146
147   const { url, username, password } = await getServerCredentials(options)
148   const accessToken = await getAdminTokenOrDie(url, username, password)
149
150   try {
151     await updatePlugin({
152       url,
153       accessToken,
154       npmName: options['npmName'],
155       path: options['path']
156     })
157   } catch (err) {
158     console.error('Cannot update plugin.', err)
159     process.exit(-1)
160     return
161   }
162
163   console.log('Plugin updated.')
164   process.exit(0)
165 }
166
167 async function uninstallPluginCLI (options: any) {
168   if (!options['npmName']) {
169     console.error('You need to specify the npm name of the plugin/theme you want to uninstall.\n')
170     program.outputHelp()
171     process.exit(-1)
172   }
173
174   const { url, username, password } = await getServerCredentials(options)
175   const accessToken = await getAdminTokenOrDie(url, username, password)
176
177   try {
178     await uninstallPlugin({
179       url,
180       accessToken,
181       npmName: options[ 'npmName' ]
182     })
183   } catch (err) {
184     console.error('Cannot uninstall plugin.', err)
185     process.exit(-1)
186     return
187   }
188
189   console.log('Plugin uninstalled.')
190   process.exit(0)
191 }
192
193 async function getAdminTokenOrDie (url: string, username: string, password: string) {
194   const accessToken = await getAccessToken(url, username, password)
195   const resMe = await getMyUserInformation(url, accessToken)
196   const me: User = resMe.body
197
198   if (me.role !== UserRole.ADMINISTRATOR) {
199     console.error('Cannot list plugins if you are not administrator.')
200     process.exit(-1)
201   }
202
203   return accessToken
204 }