Add disable webtorrent migration
[oweals/peertube.git] / server / initializers / installer.ts
1 import * as passwordGenerator from 'password-generator'
2 import { UserRole } from '../../shared'
3 import { logger } from '../helpers/logger'
4 import { createApplicationActor, createUserAccountAndChannelAndPlaylist } from '../lib/user'
5 import { UserModel } from '../models/account/user'
6 import { ApplicationModel } from '../models/application/application'
7 import { OAuthClientModel } from '../models/oauth/oauth-client'
8 import { applicationExist, clientsExist, usersExist } from './checker-after-init'
9 import { FILES_CACHE, HLS_STREAMING_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION } from './constants'
10 import { sequelizeTypescript } from './database'
11 import { ensureDir, remove } from 'fs-extra'
12 import { CONFIG } from './config'
13
14 async function installApplication () {
15   try {
16     await Promise.all([
17       // Database related
18       sequelizeTypescript.sync()
19         .then(() => {
20           return Promise.all([
21             createApplicationIfNotExist(),
22             createOAuthClientIfNotExist(),
23             createOAuthAdminIfNotExist()
24           ])
25         }),
26
27       // Directories
28       removeCacheAndTmpDirectories()
29         .then(() => createDirectoriesIfNotExist())
30     ])
31   } catch (err) {
32     logger.error('Cannot install application.', { err })
33     process.exit(-1)
34   }
35 }
36
37 // ---------------------------------------------------------------------------
38
39 export {
40   installApplication
41 }
42
43 // ---------------------------------------------------------------------------
44
45 function removeCacheAndTmpDirectories () {
46   const cacheDirectories = Object.keys(FILES_CACHE)
47     .map(k => FILES_CACHE[k].DIRECTORY)
48
49   const tasks: Promise<any>[] = []
50
51   // Cache directories
52   for (const key of Object.keys(cacheDirectories)) {
53     const dir = cacheDirectories[key]
54     tasks.push(remove(dir))
55   }
56
57   tasks.push(remove(CONFIG.STORAGE.TMP_DIR))
58
59   return Promise.all(tasks)
60 }
61
62 function createDirectoriesIfNotExist () {
63   const storage = CONFIG.STORAGE
64   const cacheDirectories = Object.keys(FILES_CACHE)
65                                  .map(k => FILES_CACHE[k].DIRECTORY)
66
67   const tasks: Promise<void>[] = []
68   for (const key of Object.keys(storage)) {
69     const dir = storage[key]
70     tasks.push(ensureDir(dir))
71   }
72
73   // Cache directories
74   for (const key of Object.keys(cacheDirectories)) {
75     const dir = cacheDirectories[key]
76     tasks.push(ensureDir(dir))
77   }
78
79   // Playlist directories
80   tasks.push(ensureDir(HLS_STREAMING_PLAYLIST_DIRECTORY))
81
82   return Promise.all(tasks)
83 }
84
85 async function createOAuthClientIfNotExist () {
86   const exist = await clientsExist()
87   // Nothing to do, clients already exist
88   if (exist === true) return undefined
89
90   logger.info('Creating a default OAuth Client.')
91
92   const id = passwordGenerator(32, false, /[a-z0-9]/)
93   const secret = passwordGenerator(32, false, /[a-zA-Z0-9]/)
94   const client = new OAuthClientModel({
95     clientId: id,
96     clientSecret: secret,
97     grants: [ 'password', 'refresh_token' ],
98     redirectUris: null
99   })
100
101   const createdClient = await client.save()
102   logger.info('Client id: ' + createdClient.clientId)
103   logger.info('Client secret: ' + createdClient.clientSecret)
104
105   return undefined
106 }
107
108 async function createOAuthAdminIfNotExist () {
109   const exist = await usersExist()
110   // Nothing to do, users already exist
111   if (exist === true) return undefined
112
113   logger.info('Creating the administrator.')
114
115   const username = 'root'
116   const role = UserRole.ADMINISTRATOR
117   const email = CONFIG.ADMIN.EMAIL
118   let validatePassword = true
119   let password = ''
120
121   // Do not generate a random password for tests
122   if (process.env.NODE_ENV === 'test') {
123     password = 'test'
124
125     if (process.env.NODE_APP_INSTANCE) {
126       password += process.env.NODE_APP_INSTANCE
127     }
128
129     // Our password is weak so do not validate it
130     validatePassword = false
131   } else if (process.env.PT_INITIAL_ROOT_PASSWORD) {
132     password = process.env.PT_INITIAL_ROOT_PASSWORD
133   } else {
134     password = passwordGenerator(16, true)
135   }
136
137   const userData = {
138     username,
139     email,
140     password,
141     role,
142     verified: true,
143     nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
144     videoQuota: -1,
145     videoQuotaDaily: -1
146   }
147   const user = new UserModel(userData)
148
149   await createUserAccountAndChannelAndPlaylist({ userToCreate: user, channelNames: undefined, validateUser: validatePassword })
150   logger.info('Username: ' + username)
151   logger.info('User password: ' + password)
152 }
153
154 async function createApplicationIfNotExist () {
155   const exist = await applicationExist()
156   // Nothing to do, application already exist
157   if (exist === true) return undefined
158
159   logger.info('Creating application account.')
160
161   const application = await ApplicationModel.create({
162     migrationVersion: LAST_MIGRATION_VERSION
163   })
164
165   return createApplicationActor(application.id)
166 }