Support roles with rights and add moderator role
[oweals/peertube.git] / server / helpers / core-utils.ts
1 /*
2   Different from 'utils' because we don't not import other PeerTube modules.
3   Useful to avoid circular dependencies.
4 */
5
6 import { join } from 'path'
7 import { pseudoRandomBytes } from 'crypto'
8 import {
9   readdir,
10   readFile,
11   rename,
12   unlink,
13   writeFile,
14   access,
15   stat,
16   Stats
17 } from 'fs'
18 import * as mkdirp from 'mkdirp'
19 import * as bcrypt from 'bcrypt'
20 import * as createTorrent from 'create-torrent'
21 import * as rimraf from 'rimraf'
22 import * as openssl from 'openssl-wrapper'
23 import * as Promise from 'bluebird'
24
25 function isTestInstance () {
26   return process.env.NODE_ENV === 'test'
27 }
28
29 function root () {
30   // We are in /helpers/utils.js
31   const paths = [ __dirname, '..', '..' ]
32
33   // We are under /dist directory
34   if (process.mainModule.filename.endsWith('.ts') === false) {
35     paths.push('..')
36   }
37
38   return join.apply(null, paths)
39 }
40
41 // Thanks: https://stackoverflow.com/a/12034334
42 function escapeHTML (stringParam) {
43   const entityMap = {
44     '&': '&',
45     '<': '&lt;',
46     '>': '&gt;',
47     '"': '&quot;',
48     "'": '&#39;',
49     '/': '&#x2F;',
50     '`': '&#x60;',
51     '=': '&#x3D;'
52   }
53
54   return String(stringParam).replace(/[&<>"'`=\/]/g, s => entityMap[s])
55 }
56
57 function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> {
58   return function promisified (): Promise<A> {
59     return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
60       func.apply(null, [ (err: any, res: A) => err ? reject(err) : resolve(res) ])
61     })
62   }
63 }
64
65 // Thanks to https://gist.github.com/kumasento/617daa7e46f13ecdd9b2
66 function promisify1<T, A> (func: (arg: T, cb: (err: any, result: A) => void) => void): (arg: T) => Promise<A> {
67   return function promisified (arg: T): Promise<A> {
68     return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
69       func.apply(null, [ arg, (err: any, res: A) => err ? reject(err) : resolve(res) ])
70     })
71   }
72 }
73
74 function promisify1WithVoid<T> (func: (arg: T, cb: (err: any) => void) => void): (arg: T) => Promise<void> {
75   return function promisified (arg: T): Promise<void> {
76     return new Promise<void>((resolve: () => void, reject: (err: any) => void) => {
77       func.apply(null, [ arg, (err: any) => err ? reject(err) : resolve() ])
78     })
79   }
80 }
81
82 function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A) => void) => void): (arg1: T, arg2: U) => Promise<A> {
83   return function promisified (arg1: T, arg2: U): Promise<A> {
84     return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
85       func.apply(null, [ arg1, arg2, (err: any, res: A) => err ? reject(err) : resolve(res) ])
86     })
87   }
88 }
89
90 function promisify2WithVoid<T, U> (func: (arg1: T, arg2: U, cb: (err: any) => void) => void): (arg1: T, arg2: U) => Promise<void> {
91   return function promisified (arg1: T, arg2: U): Promise<void> {
92     return new Promise<void>((resolve: () => void, reject: (err: any) => void) => {
93       func.apply(null, [ arg1, arg2, (err: any) => err ? reject(err) : resolve() ])
94     })
95   }
96 }
97
98 const readFilePromise = promisify2<string, string, string>(readFile)
99 const readFileBufferPromise = promisify1<string, Buffer>(readFile)
100 const unlinkPromise = promisify1WithVoid<string>(unlink)
101 const renamePromise = promisify2WithVoid<string, string>(rename)
102 const writeFilePromise = promisify2WithVoid<string, any>(writeFile)
103 const readdirPromise = promisify1<string, string[]>(readdir)
104 const mkdirpPromise = promisify1<string, string>(mkdirp)
105 const pseudoRandomBytesPromise = promisify1<number, Buffer>(pseudoRandomBytes)
106 const accessPromise = promisify1WithVoid<string|Buffer>(access)
107 const opensslExecPromise = promisify2WithVoid<string, any>(openssl.exec)
108 const bcryptComparePromise = promisify2<any, string, boolean>(bcrypt.compare)
109 const bcryptGenSaltPromise = promisify1<number, string>(bcrypt.genSalt)
110 const bcryptHashPromise = promisify2<any, string|number, string>(bcrypt.hash)
111 const createTorrentPromise = promisify2<string, any, any>(createTorrent)
112 const rimrafPromise = promisify1WithVoid<string>(rimraf)
113 const statPromise = promisify1<string, Stats>(stat)
114
115 // ---------------------------------------------------------------------------
116
117 export {
118   isTestInstance,
119   root,
120   escapeHTML,
121
122   promisify0,
123   promisify1,
124   readdirPromise,
125   readFilePromise,
126   readFileBufferPromise,
127   unlinkPromise,
128   renamePromise,
129   writeFilePromise,
130   mkdirpPromise,
131   pseudoRandomBytesPromise,
132   accessPromise,
133   opensslExecPromise,
134   bcryptComparePromise,
135   bcryptGenSaltPromise,
136   bcryptHashPromise,
137   createTorrentPromise,
138   rimrafPromise,
139   statPromise
140 }