]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - src/utils.js
Add link to the ARCHITECTURE.md
[github/Chocobozzz/PeerTube.git] / src / utils.js
CommitLineData
8c308c2b
C
1;(function () {
2 'use strict'
3
4 var request = require('request')
5 var replay = require('request-replay')
6 var ursa = require('ursa')
7 var config = require('config')
8 var fs = require('fs')
9 var openssl = require('openssl-wrapper')
10 var crypto = require('crypto')
11
12 var logger = require('./logger')
13
14 var http = config.get('webserver.https') ? 'https' : 'http'
15 var host = config.get('webserver.host')
16 var port = config.get('webserver.port')
17 var algorithm = 'aes-256-ctr'
18
19 var utils = {}
20
21 // ----------- Private functions ----------
22
23 function makeRetryRequest (params, from_url, to_pod, signature, callbackEach) {
24 // Append the signature
25 if (signature) {
26 params.json.signature = {
27 url: from_url,
28 signature: signature
29 }
30 }
31
32 logger.debug('Sending informations to %s', to_pod.url, { params: params })
33
34 // Replay 15 times, with factor 3
35 replay(
36 request.post(params, function (err, response, body) {
37 callbackEach(err, response, body, to_pod.url)
38 }),
39 {
40 retries: 10,
41 factor: 3,
42 maxTimeout: Infinity,
43 errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ]
44 }
45 ).on('replay', function (replay) {
46 logger.info('Replaying request to %s. Request failed: %d %s. Replay number: #%d. Will retry in: %d ms.',
47 params.url, replay.error.code, replay.error.message, replay.number, replay.delay)
48 })
49 }
50
51 // ----------- Public attributes ----------
52 utils.certDir = __dirname + '/../' + config.get('storage.certs')
53
54 // { path, data }
55 utils.makeMultipleRetryRequest = function (all, pods, callbackEach, callback) {
56 if (!callback) {
57 callback = callbackEach
58 callbackEach = function () {}
59 }
60
61 var url = http + '://' + host + ':' + port
62 var signature
63
64 // Signature ?
65 if (all.method === 'POST' && all.data && all.sign === true) {
66 var myKey = ursa.createPrivateKey(fs.readFileSync(utils.certDir + 'petube.key.pem'))
67 signature = myKey.hashAndSign('sha256', url, 'utf8', 'hex')
68 }
69
70 // Make a request for each pod
71 for (var pod of pods) {
72 var params = {
73 url: pod.url + all.path,
74 method: all.method
75 }
76
77 // Add data with POST requst ?
78 if (all.method === 'POST' && all.data) {
79 logger.debug('Make a POST request.')
80
81 // Encrypt data ?
82 if (all.encrypt === true) {
83 logger.debug(pod.publicKey)
84 var crt = ursa.createPublicKey(pod.publicKey)
85
86 // TODO: ES6 with let
87 ;(function (crt_copy, copy_params, copy_url, copy_pod, copy_signature) {
88 utils.symetricEncrypt(JSON.stringify(all.data), function (err, dataEncrypted) {
89 if (err) throw err
90
91 var passwordEncrypted = crt_copy.encrypt(dataEncrypted.password, 'utf8', 'hex')
92 copy_params.json = {
93 data: dataEncrypted.crypted,
94 key: passwordEncrypted
95 }
96
97 makeRetryRequest(copy_params, copy_url, copy_pod, copy_signature, callbackEach)
98 })
99 })(crt, params, url, pod, signature)
100 } else {
101 params.json = { data: all.data }
102 makeRetryRequest(params, url, pod, signature, callbackEach)
103 }
104 } else {
105 logger.debug('Make a GET/DELETE request')
106 makeRetryRequest(params, url, pod, signature, callbackEach)
107 }
108 }
109
110 return callback()
111 }
112
113 utils.certsExist = function (callback) {
114 fs.exists(utils.certDir + 'petube.key.pem', function (exists) {
115 return callback(exists)
116 })
117 }
118
119 utils.createCerts = function (callback) {
120 utils.certsExist(function (exist) {
121 if (exist === true) {
122 var string = 'Certs already exist.'
123 logger.warning(string)
124 return callback(new Error(string))
125 }
126
127 logger.debug('Gen RSA keys...')
128 openssl.exec('genrsa', { 'out': utils.certDir + 'petube.key.pem' }, function (err) {
129 if (err) {
130 logger.error('Cannot create private key on this pod.', { error: err })
131 return callback(err)
132 }
133
134 logger.debug('Manage public key...')
135 openssl.exec('rsa', { 'in': utils.certDir + 'petube.key.pem', 'pubout': true, 'out': utils.certDir + 'petube.pub' }, function (err) {
136 if (err) {
137 logger.error('Cannot create public key on this pod .', { error: err })
138 return callback(err)
139 }
140
141 return callback(null)
142 })
143 })
144 })
145 }
146
147 utils.createCertsIfNotExist = function (callback) {
148 utils.certsExist(function (exist) {
149 if (exist === true) {
150 return callback(null)
151 }
152
153 utils.createCerts(function (err) {
154 return callback(err)
155 })
156 })
157 }
158
159 utils.generatePassword = function (callback) {
160 crypto.randomBytes(32, function (err, buf) {
161 if (err) {
162 return callback(err)
163 }
164
165 callback(null, buf.toString('utf8'))
166 })
167 }
168
169 utils.symetricEncrypt = function (text, callback) {
170 utils.generatePassword(function (err, password) {
171 if (err) {
172 return callback(err)
173 }
174
175 var cipher = crypto.createCipher(algorithm, password)
176 var crypted = cipher.update(text, 'utf8', 'hex')
177 crypted += cipher.final('hex')
178 callback(null, { crypted: crypted, password: password })
179 })
180 }
181
182 utils.symetricDecrypt = function (text, password) {
183 var decipher = crypto.createDecipher(algorithm, password)
184 var dec = decipher.update(text, 'hex', 'utf8')
185 dec += decipher.final('utf8')
186 return dec
187 }
188
189 module.exports = utils
190})()