aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers/utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/helpers/utils.ts')
-rw-r--r--server/helpers/utils.ts151
1 files changed, 7 insertions, 144 deletions
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts
index eaad55555..703e57887 100644
--- a/server/helpers/utils.ts
+++ b/server/helpers/utils.ts
@@ -1,37 +1,12 @@
1import { Model } from 'sequelize-typescript'
2import * as ipaddr from 'ipaddr.js'
3import { ResultList } from '../../shared' 1import { ResultList } from '../../shared'
4import { VideoResolution } from '../../shared/models/videos'
5import { CONFIG } from '../initializers' 2import { CONFIG } from '../initializers'
6import { UserModel } from '../models/account/user'
7import { ActorModel } from '../models/activitypub/actor' 3import { ActorModel } from '../models/activitypub/actor'
8import { ApplicationModel } from '../models/application/application' 4import { ApplicationModel } from '../models/application/application'
9import { pseudoRandomBytesPromise, sha256, unlinkPromise } from './core-utils' 5import { pseudoRandomBytesPromise, sha256, unlinkPromise } from './core-utils'
10import { logger } from './logger' 6import { logger } from './logger'
11import { isArray } from './custom-validators/misc'
12import { join } from 'path' 7import { join } from 'path'
13import { Instance as ParseTorrent } from 'parse-torrent' 8import { Instance as ParseTorrent } from 'parse-torrent'
14 9
15const isCidr = require('is-cidr')
16
17function cleanUpReqFiles (req: { files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[] }) {
18 const files = req.files
19
20 if (!files) return
21
22 if (isArray(files)) {
23 (files as Express.Multer.File[]).forEach(f => deleteFileAsync(f.path))
24 return
25 }
26
27 for (const key of Object.keys(files)) {
28 const file = files[key]
29
30 if (isArray(file)) file.forEach(f => deleteFileAsync(f.path))
31 else deleteFileAsync(file.path)
32 }
33}
34
35function deleteFileAsync (path: string) { 10function deleteFileAsync (path: string) {
36 unlinkPromise(path) 11 unlinkPromise(path)
37 .catch(err => logger.error('Cannot delete the file %s asynchronously.', path, { err })) 12 .catch(err => logger.error('Cannot delete the file %s asynchronously.', path, { err }))
@@ -60,127 +35,23 @@ function getFormattedObjects<U, T extends FormattableToJSON> (objects: T[], obje
60 } as ResultList<U> 35 } as ResultList<U>
61} 36}
62 37
63async function isSignupAllowed () {
64 if (CONFIG.SIGNUP.ENABLED === false) {
65 return false
66 }
67
68 // No limit and signup is enabled
69 if (CONFIG.SIGNUP.LIMIT === -1) {
70 return true
71 }
72
73 const totalUsers = await UserModel.countTotal()
74
75 return totalUsers < CONFIG.SIGNUP.LIMIT
76}
77
78function isSignupAllowedForCurrentIP (ip: string) {
79 const addr = ipaddr.parse(ip)
80 let excludeList = [ 'blacklist' ]
81 let matched = ''
82
83 // if there is a valid, non-empty whitelist, we exclude all unknown adresses too
84 if (CONFIG.SIGNUP.FILTERS.CIDR.WHITELIST.filter(cidr => isCidr(cidr)).length > 0) {
85 excludeList.push('unknown')
86 }
87
88 if (addr.kind() === 'ipv4') {
89 const addrV4 = ipaddr.IPv4.parse(ip)
90 const rangeList = {
91 whitelist: CONFIG.SIGNUP.FILTERS.CIDR.WHITELIST.filter(cidr => isCidr.v4(cidr))
92 .map(cidr => ipaddr.IPv4.parseCIDR(cidr)),
93 blacklist: CONFIG.SIGNUP.FILTERS.CIDR.BLACKLIST.filter(cidr => isCidr.v4(cidr))
94 .map(cidr => ipaddr.IPv4.parseCIDR(cidr))
95 }
96 matched = ipaddr.subnetMatch(addrV4, rangeList, 'unknown')
97 } else if (addr.kind() === 'ipv6') {
98 const addrV6 = ipaddr.IPv6.parse(ip)
99 const rangeList = {
100 whitelist: CONFIG.SIGNUP.FILTERS.CIDR.WHITELIST.filter(cidr => isCidr.v6(cidr))
101 .map(cidr => ipaddr.IPv6.parseCIDR(cidr)),
102 blacklist: CONFIG.SIGNUP.FILTERS.CIDR.BLACKLIST.filter(cidr => isCidr.v6(cidr))
103 .map(cidr => ipaddr.IPv6.parseCIDR(cidr))
104 }
105 matched = ipaddr.subnetMatch(addrV6, rangeList, 'unknown')
106 }
107
108 return !excludeList.includes(matched)
109}
110
111function computeResolutionsToTranscode (videoFileHeight: number) {
112 const resolutionsEnabled: number[] = []
113 const configResolutions = CONFIG.TRANSCODING.RESOLUTIONS
114
115 // Put in the order we want to proceed jobs
116 const resolutions = [
117 VideoResolution.H_480P,
118 VideoResolution.H_360P,
119 VideoResolution.H_720P,
120 VideoResolution.H_240P,
121 VideoResolution.H_1080P
122 ]
123
124 for (const resolution of resolutions) {
125 if (configResolutions[ resolution + 'p' ] === true && videoFileHeight > resolution) {
126 resolutionsEnabled.push(resolution)
127 }
128 }
129
130 return resolutionsEnabled
131}
132
133const timeTable = {
134 ms: 1,
135 second: 1000,
136 minute: 60000,
137 hour: 3600000,
138 day: 3600000 * 24,
139 week: 3600000 * 24 * 7,
140 month: 3600000 * 24 * 30
141}
142export function parseDuration (duration: number | string): number {
143 if (typeof duration === 'number') return duration
144
145 if (typeof duration === 'string') {
146 const split = duration.match(/^([\d\.,]+)\s?(\w+)$/)
147
148 if (split.length === 3) {
149 const len = parseFloat(split[1])
150 let unit = split[2].replace(/s$/i,'').toLowerCase()
151 if (unit === 'm') {
152 unit = 'ms'
153 }
154
155 return (len || 1) * (timeTable[unit] || 0)
156 }
157 }
158
159 throw new Error('Duration could not be properly parsed')
160}
161
162function resetSequelizeInstance (instance: Model<any>, savedFields: object) {
163 Object.keys(savedFields).forEach(key => {
164 const value = savedFields[key]
165 instance.set(key, value)
166 })
167}
168
169let serverActor: ActorModel
170async function getServerActor () { 38async function getServerActor () {
171 if (serverActor === undefined) { 39 if (getServerActor.serverActor === undefined) {
172 const application = await ApplicationModel.load() 40 const application = await ApplicationModel.load()
173 if (!application) throw Error('Could not load Application from database.') 41 if (!application) throw Error('Could not load Application from database.')
174 42
175 serverActor = application.Account.Actor 43 getServerActor.serverActor = application.Account.Actor
176 } 44 }
177 45
178 if (!serverActor) { 46 if (!getServerActor.serverActor) {
179 logger.error('Cannot load server actor.') 47 logger.error('Cannot load server actor.')
180 process.exit(0) 48 process.exit(0)
181 } 49 }
182 50
183 return Promise.resolve(serverActor) 51 return Promise.resolve(getServerActor.serverActor)
52}
53namespace getServerActor {
54 export let serverActor: ActorModel
184} 55}
185 56
186function generateVideoTmpPath (target: string | ParseTorrent) { 57function generateVideoTmpPath (target: string | ParseTorrent) {
@@ -194,21 +65,13 @@ function getSecureTorrentName (originalName: string) {
194 return sha256(originalName) + '.torrent' 65 return sha256(originalName) + '.torrent'
195} 66}
196 67
197type SortType = { sortModel: any, sortValue: string }
198
199// --------------------------------------------------------------------------- 68// ---------------------------------------------------------------------------
200 69
201export { 70export {
202 cleanUpReqFiles,
203 deleteFileAsync, 71 deleteFileAsync,
204 generateRandomString, 72 generateRandomString,
205 getFormattedObjects, 73 getFormattedObjects,
206 isSignupAllowed,
207 getSecureTorrentName, 74 getSecureTorrentName,
208 isSignupAllowedForCurrentIP,
209 computeResolutionsToTranscode,
210 resetSequelizeInstance,
211 getServerActor, 75 getServerActor,
212 SortType,
213 generateVideoTmpPath 76 generateVideoTmpPath
214} 77}